blob: 9e7a3b4568e932a91da9d48a129ee3f3633c0a59 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Masti, Narayanraddie1892a52015-12-15 15:01:01 +05302 * Copyright (c) 2012-2016 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
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530183#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
184
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530185
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530186static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700187{
188 WLAN_CIPHER_SUITE_WEP40,
189 WLAN_CIPHER_SUITE_WEP104,
190 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800191#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700192#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
193 WLAN_CIPHER_SUITE_KRK,
194 WLAN_CIPHER_SUITE_CCMP,
195#else
196 WLAN_CIPHER_SUITE_CCMP,
197#endif
198#ifdef FEATURE_WLAN_WAPI
199 WLAN_CIPHER_SUITE_SMS4,
200#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700201#ifdef WLAN_FEATURE_11W
202 WLAN_CIPHER_SUITE_AES_CMAC,
203#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700204};
205
206static inline int is_broadcast_ether_addr(const u8 *addr)
207{
208 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
209 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
210}
211
Agrawal Ashish97dec502015-11-26 20:20:58 +0530212const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530213{
Jeff Johnson295189b2012-06-20 16:38:30 -0700214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2417, 2, 0) ,
216 HDD2GHZCHAN(2422, 3, 0) ,
217 HDD2GHZCHAN(2427, 4, 0) ,
218 HDD2GHZCHAN(2432, 5, 0) ,
219 HDD2GHZCHAN(2437, 6, 0) ,
220 HDD2GHZCHAN(2442, 7, 0) ,
221 HDD2GHZCHAN(2447, 8, 0) ,
222 HDD2GHZCHAN(2452, 9, 0) ,
223 HDD2GHZCHAN(2457, 10, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225 HDD2GHZCHAN(2467, 12, 0) ,
226 HDD2GHZCHAN(2472, 13, 0) ,
227 HDD2GHZCHAN(2484, 14, 0) ,
228};
229
Agrawal Ashish97dec502015-11-26 20:20:58 +0530230const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700231{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700232 HDD5GHZCHAN(4920, 240, 0) ,
233 HDD5GHZCHAN(4940, 244, 0) ,
234 HDD5GHZCHAN(4960, 248, 0) ,
235 HDD5GHZCHAN(4980, 252, 0) ,
236 HDD5GHZCHAN(5040, 208, 0) ,
237 HDD5GHZCHAN(5060, 212, 0) ,
238 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD5GHZCHAN(5180, 36, 0) ,
240 HDD5GHZCHAN(5200, 40, 0) ,
241 HDD5GHZCHAN(5220, 44, 0) ,
242 HDD5GHZCHAN(5240, 48, 0) ,
243 HDD5GHZCHAN(5260, 52, 0) ,
244 HDD5GHZCHAN(5280, 56, 0) ,
245 HDD5GHZCHAN(5300, 60, 0) ,
246 HDD5GHZCHAN(5320, 64, 0) ,
247 HDD5GHZCHAN(5500,100, 0) ,
248 HDD5GHZCHAN(5520,104, 0) ,
249 HDD5GHZCHAN(5540,108, 0) ,
250 HDD5GHZCHAN(5560,112, 0) ,
251 HDD5GHZCHAN(5580,116, 0) ,
252 HDD5GHZCHAN(5600,120, 0) ,
253 HDD5GHZCHAN(5620,124, 0) ,
254 HDD5GHZCHAN(5640,128, 0) ,
255 HDD5GHZCHAN(5660,132, 0) ,
256 HDD5GHZCHAN(5680,136, 0) ,
257 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800258#ifdef FEATURE_WLAN_CH144
259 HDD5GHZCHAN(5720,144, 0) ,
260#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 HDD5GHZCHAN(5745,149, 0) ,
262 HDD5GHZCHAN(5765,153, 0) ,
263 HDD5GHZCHAN(5785,157, 0) ,
264 HDD5GHZCHAN(5805,161, 0) ,
265 HDD5GHZCHAN(5825,165, 0) ,
266};
267
268static struct ieee80211_rate g_mode_rates[] =
269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530270 HDD_G_MODE_RATETAB(10, 0x1, 0),
271 HDD_G_MODE_RATETAB(20, 0x2, 0),
272 HDD_G_MODE_RATETAB(55, 0x4, 0),
273 HDD_G_MODE_RATETAB(110, 0x8, 0),
274 HDD_G_MODE_RATETAB(60, 0x10, 0),
275 HDD_G_MODE_RATETAB(90, 0x20, 0),
276 HDD_G_MODE_RATETAB(120, 0x40, 0),
277 HDD_G_MODE_RATETAB(180, 0x80, 0),
278 HDD_G_MODE_RATETAB(240, 0x100, 0),
279 HDD_G_MODE_RATETAB(360, 0x200, 0),
280 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282};
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
284static struct ieee80211_rate a_mode_rates[] =
285{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530286 HDD_G_MODE_RATETAB(60, 0x10, 0),
287 HDD_G_MODE_RATETAB(90, 0x20, 0),
288 HDD_G_MODE_RATETAB(120, 0x40, 0),
289 HDD_G_MODE_RATETAB(180, 0x80, 0),
290 HDD_G_MODE_RATETAB(240, 0x100, 0),
291 HDD_G_MODE_RATETAB(360, 0x200, 0),
292 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 HDD_G_MODE_RATETAB(540, 0x800, 0),
294};
295
296static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
297{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530298 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700299 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
300 .band = IEEE80211_BAND_2GHZ,
301 .bitrates = g_mode_rates,
302 .n_bitrates = g_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
308 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
309 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
310 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
311 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
312 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
313};
314
Jeff Johnson295189b2012-06-20 16:38:30 -0700315static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
316{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530317 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
319 .band = IEEE80211_BAND_5GHZ,
320 .bitrates = a_mode_rates,
321 .n_bitrates = a_mode_rates_size,
322 .ht_cap.ht_supported = 1,
323 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
324 | IEEE80211_HT_CAP_GRN_FLD
325 | IEEE80211_HT_CAP_DSSSCCK40
326 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
327 | IEEE80211_HT_CAP_SGI_40
328 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
329 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
330 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
331 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
332 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
333 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
334};
335
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530336/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 TX/RX direction for each kind of interface */
338static const struct ieee80211_txrx_stypes
339wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
340 [NL80211_IFTYPE_STATION] = {
341 .tx = 0xffff,
342 .rx = BIT(SIR_MAC_MGMT_ACTION) |
343 BIT(SIR_MAC_MGMT_PROBE_REQ),
344 },
345 [NL80211_IFTYPE_AP] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
348 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
349 BIT(SIR_MAC_MGMT_PROBE_REQ) |
350 BIT(SIR_MAC_MGMT_DISASSOC) |
351 BIT(SIR_MAC_MGMT_AUTH) |
352 BIT(SIR_MAC_MGMT_DEAUTH) |
353 BIT(SIR_MAC_MGMT_ACTION),
354 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700355 [NL80211_IFTYPE_ADHOC] = {
356 .tx = 0xffff,
357 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
358 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
359 BIT(SIR_MAC_MGMT_PROBE_REQ) |
360 BIT(SIR_MAC_MGMT_DISASSOC) |
361 BIT(SIR_MAC_MGMT_AUTH) |
362 BIT(SIR_MAC_MGMT_DEAUTH) |
363 BIT(SIR_MAC_MGMT_ACTION),
364 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 [NL80211_IFTYPE_P2P_CLIENT] = {
366 .tx = 0xffff,
367 .rx = BIT(SIR_MAC_MGMT_ACTION) |
368 BIT(SIR_MAC_MGMT_PROBE_REQ),
369 },
370 [NL80211_IFTYPE_P2P_GO] = {
371 /* This is also same as for SoftAP */
372 .tx = 0xffff,
373 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ) |
376 BIT(SIR_MAC_MGMT_DISASSOC) |
377 BIT(SIR_MAC_MGMT_AUTH) |
378 BIT(SIR_MAC_MGMT_DEAUTH) |
379 BIT(SIR_MAC_MGMT_ACTION),
380 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700381};
382
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800383#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800384static const struct ieee80211_iface_limit
385wlan_hdd_iface_limit[] = {
386 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800387 /* max = 3 ; Our driver create two interfaces during driver init
388 * wlan0 and p2p0 interfaces. p2p0 is considered as station
389 * interface until a group is formed. In JB architecture, once the
390 * group is formed, interface type of p2p0 is changed to P2P GO or
391 * Client.
392 * When supplicant remove the group, it first issue a set interface
393 * cmd to change the mode back to Station. In JB this works fine as
394 * we advertize two station type interface during driver init.
395 * Some vendors create separate interface for P2P GO/Client,
396 * after group formation(Third one). But while group remove
397 * supplicant first tries to change the mode(3rd interface) to STATION
398 * But as we advertized only two sta type interfaces nl80211 was
399 * returning error for the third one which was leading to failure in
400 * delete interface. Ideally while removing the group, supplicant
401 * should not try to change the 3rd interface mode to Station type.
402 * Till we get a fix in wpa_supplicant, we advertize max STA
403 * interface type to 3
404 */
405 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800406 .types = BIT(NL80211_IFTYPE_STATION),
407 },
408 {
409 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700410 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 },
412 {
413 .max = 1,
414 .types = BIT(NL80211_IFTYPE_P2P_GO) |
415 BIT(NL80211_IFTYPE_P2P_CLIENT),
416 },
417};
418
419/* By default, only single channel concurrency is allowed */
420static struct ieee80211_iface_combination
421wlan_hdd_iface_combination = {
422 .limits = wlan_hdd_iface_limit,
423 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800424 /*
425 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
426 * and p2p0 interfaces during driver init
427 * Some vendors create separate interface for P2P operations.
428 * wlan0: STA interface
429 * p2p0: P2P Device interface, action frames goes
430 * through this interface.
431 * p2p-xx: P2P interface, After GO negotiation this interface is
432 * created for p2p operations(GO/CLIENT interface).
433 */
434 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800435 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
436 .beacon_int_infra_match = false,
437};
438#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800439
Jeff Johnson295189b2012-06-20 16:38:30 -0700440static struct cfg80211_ops wlan_hdd_cfg80211_ops;
441
442/* Data rate 100KBPS based on IE Index */
443struct index_data_rate_type
444{
445 v_U8_t beacon_rate_index;
446 v_U16_t supported_rate[4];
447};
448
449/* 11B, 11G Rate table include Basic rate and Extended rate
450 The IDX field is the rate index
451 The HI field is the rate when RSSI is strong or being ignored
452 (in this case we report actual rate)
453 The MID field is the rate when RSSI is moderate
454 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
455 The LO field is the rate when RSSI is low
456 (in this case we don't report rates, actual current rate used)
457 */
458static const struct
459{
460 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700461 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700462} supported_data_rate[] =
463{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700464/* IDX HI HM LM LO (RSSI-based index */
465 {2, { 10, 10, 10, 0}},
466 {4, { 20, 20, 10, 0}},
467 {11, { 55, 20, 10, 0}},
468 {12, { 60, 55, 20, 0}},
469 {18, { 90, 55, 20, 0}},
470 {22, {110, 55, 20, 0}},
471 {24, {120, 90, 60, 0}},
472 {36, {180, 120, 60, 0}},
473 {44, {220, 180, 60, 0}},
474 {48, {240, 180, 90, 0}},
475 {66, {330, 180, 90, 0}},
476 {72, {360, 240, 90, 0}},
477 {96, {480, 240, 120, 0}},
478 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700479};
480
481/* MCS Based rate table */
482static struct index_data_rate_type supported_mcs_rate[] =
483{
484/* MCS L20 L40 S20 S40 */
485 {0, {65, 135, 72, 150}},
486 {1, {130, 270, 144, 300}},
487 {2, {195, 405, 217, 450}},
488 {3, {260, 540, 289, 600}},
489 {4, {390, 810, 433, 900}},
490 {5, {520, 1080, 578, 1200}},
491 {6, {585, 1215, 650, 1350}},
492 {7, {650, 1350, 722, 1500}}
493};
494
Leo Chang6f8870f2013-03-26 18:11:36 -0700495#ifdef WLAN_FEATURE_11AC
496
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530497#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700498
499struct index_vht_data_rate_type
500{
501 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530502 v_U16_t supported_VHT80_rate[2];
503 v_U16_t supported_VHT40_rate[2];
504 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700505};
506
507typedef enum
508{
509 DATA_RATE_11AC_MAX_MCS_7,
510 DATA_RATE_11AC_MAX_MCS_8,
511 DATA_RATE_11AC_MAX_MCS_9,
512 DATA_RATE_11AC_MAX_MCS_NA
513} eDataRate11ACMaxMcs;
514
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530515/* SSID broadcast type */
516typedef enum eSSIDBcastType
517{
518 eBCAST_UNKNOWN = 0,
519 eBCAST_NORMAL = 1,
520 eBCAST_HIDDEN = 2,
521} tSSIDBcastType;
522
Leo Chang6f8870f2013-03-26 18:11:36 -0700523/* MCS Based VHT rate table */
524static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
525{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530526/* MCS L80 S80 L40 S40 L20 S40*/
527 {0, {293, 325}, {135, 150}, {65, 72}},
528 {1, {585, 650}, {270, 300}, {130, 144}},
529 {2, {878, 975}, {405, 450}, {195, 217}},
530 {3, {1170, 1300}, {540, 600}, {260, 289}},
531 {4, {1755, 1950}, {810, 900}, {390, 433}},
532 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
533 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
534 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
535 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
536 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700537};
538#endif /* WLAN_FEATURE_11AC */
539
c_hpothu79aab322014-07-14 21:11:01 +0530540/*array index points to MCS and array value points respective rssi*/
541static int rssiMcsTbl[][10] =
542{
543/*MCS 0 1 2 3 4 5 6 7 8 9*/
544 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
545 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
546 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
547};
548
Jeff Johnson295189b2012-06-20 16:38:30 -0700549extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530550#ifdef FEATURE_WLAN_SCAN_PNO
551static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
552#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700553
Leo Chang9056f462013-08-01 19:21:11 -0700554#ifdef WLAN_NL80211_TESTMODE
555enum wlan_hdd_tm_attr
556{
557 WLAN_HDD_TM_ATTR_INVALID = 0,
558 WLAN_HDD_TM_ATTR_CMD = 1,
559 WLAN_HDD_TM_ATTR_DATA = 2,
560 WLAN_HDD_TM_ATTR_TYPE = 3,
561 /* keep last */
562 WLAN_HDD_TM_ATTR_AFTER_LAST,
563 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
564};
565
566enum wlan_hdd_tm_cmd
567{
568 WLAN_HDD_TM_CMD_WLAN_HB = 1,
569};
570
571#define WLAN_HDD_TM_DATA_MAX_LEN 5000
572
573static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
574{
575 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
576 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
577 .len = WLAN_HDD_TM_DATA_MAX_LEN },
578};
579#endif /* WLAN_NL80211_TESTMODE */
580
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800581#ifdef FEATURE_WLAN_CH_AVOID
582/*
583 * FUNCTION: wlan_hdd_send_avoid_freq_event
584 * This is called when wlan driver needs to send vendor specific
585 * avoid frequency range event to userspace
586 */
587int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
588 tHddAvoidFreqList *pAvoidFreqList)
589{
590 struct sk_buff *vendor_event;
591
592 ENTER();
593
594 if (!pHddCtx)
595 {
596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
597 "%s: HDD context is null", __func__);
598 return -1;
599 }
600
601 if (!pAvoidFreqList)
602 {
603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
604 "%s: pAvoidFreqList is null", __func__);
605 return -1;
606 }
607
608 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530609#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
610 NULL,
611#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800612 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530613 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800614 GFP_KERNEL);
615 if (!vendor_event)
616 {
617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
618 "%s: cfg80211_vendor_event_alloc failed", __func__);
619 return -1;
620 }
621
622 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
623 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
624
625 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
626
627 EXIT();
628 return 0;
629}
630#endif /* FEATURE_WLAN_CH_AVOID */
631
Srinivas Dasari030bad32015-02-18 23:23:54 +0530632/*
633 * FUNCTION: __wlan_hdd_cfg80211_nan_request
634 * This is called when wlan driver needs to send vendor specific
635 * nan request event.
636 */
637static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
638 struct wireless_dev *wdev,
639 const void *data, int data_len)
640{
641 tNanRequestReq nan_req;
642 VOS_STATUS status;
643 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530644 struct net_device *dev = wdev->netdev;
645 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
646 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530647 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
648
649 if (0 == data_len)
650 {
651 hddLog(VOS_TRACE_LEVEL_ERROR,
652 FL("NAN - Invalid Request, length = 0"));
653 return ret_val;
654 }
655
656 if (NULL == data)
657 {
658 hddLog(VOS_TRACE_LEVEL_ERROR,
659 FL("NAN - Invalid Request, data is NULL"));
660 return ret_val;
661 }
662
663 status = wlan_hdd_validate_context(pHddCtx);
664 if (0 != status)
665 {
666 hddLog(VOS_TRACE_LEVEL_ERROR,
667 FL("HDD context is not valid"));
668 return -EINVAL;
669 }
670
671 hddLog(LOG1, FL("Received NAN command"));
672 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
673 (tANI_U8 *)data, data_len);
674
675 /* check the NAN Capability */
676 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
677 {
678 hddLog(VOS_TRACE_LEVEL_ERROR,
679 FL("NAN is not supported by Firmware"));
680 return -EINVAL;
681 }
682
683 nan_req.request_data_len = data_len;
684 nan_req.request_data = data;
685
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530686 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530687 if (VOS_STATUS_SUCCESS == status)
688 {
689 ret_val = 0;
690 }
691 return ret_val;
692}
693
694/*
695 * FUNCTION: wlan_hdd_cfg80211_nan_request
696 * Wrapper to protect the nan vendor command from ssr
697 */
698static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
699 struct wireless_dev *wdev,
700 const void *data, int data_len)
701{
702 int ret;
703
704 vos_ssr_protect(__func__);
705 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
706 vos_ssr_unprotect(__func__);
707
708 return ret;
709}
710
711/*
712 * FUNCTION: wlan_hdd_cfg80211_nan_callback
713 * This is a callback function and it gets called
714 * when we need to report nan response event to
715 * upper layers.
716 */
717static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
718{
719 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
720 struct sk_buff *vendor_event;
721 int status;
722 tSirNanEvent *data;
723
724 ENTER();
725 if (NULL == msg)
726 {
727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
728 FL(" msg received here is null"));
729 return;
730 }
731 data = msg;
732
733 status = wlan_hdd_validate_context(pHddCtx);
734
735 if (0 != status)
736 {
737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
738 FL("HDD context is not valid"));
739 return;
740 }
741
742 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530743#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
744 NULL,
745#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530746 data->event_data_len +
747 NLMSG_HDRLEN,
748 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
749 GFP_KERNEL);
750
751 if (!vendor_event)
752 {
753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
754 FL("cfg80211_vendor_event_alloc failed"));
755 return;
756 }
757 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
758 data->event_data_len, data->event_data))
759 {
760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
761 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
762 kfree_skb(vendor_event);
763 return;
764 }
765 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
766 EXIT();
767}
768
769/*
770 * FUNCTION: wlan_hdd_cfg80211_nan_init
771 * This function is called to register the callback to sme layer
772 */
773inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
774{
775 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
776}
777
778
Sunil Duttc69bccb2014-05-26 21:30:20 +0530779#ifdef WLAN_FEATURE_LINK_LAYER_STATS
780
781static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
782 struct sk_buff *vendor_event)
783{
784 if (nla_put_u8(vendor_event,
785 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
786 stats->rate.preamble) ||
787 nla_put_u8(vendor_event,
788 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
789 stats->rate.nss) ||
790 nla_put_u8(vendor_event,
791 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
792 stats->rate.bw) ||
793 nla_put_u8(vendor_event,
794 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
795 stats->rate.rateMcsIdx) ||
796 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
797 stats->rate.bitrate ) ||
798 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
799 stats->txMpdu ) ||
800 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
801 stats->rxMpdu ) ||
802 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
803 stats->mpduLost ) ||
804 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
805 stats->retries) ||
806 nla_put_u32(vendor_event,
807 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
808 stats->retriesShort ) ||
809 nla_put_u32(vendor_event,
810 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
811 stats->retriesLong))
812 {
813 hddLog(VOS_TRACE_LEVEL_ERROR,
814 FL("QCA_WLAN_VENDOR_ATTR put fail"));
815 return FALSE;
816 }
817 return TRUE;
818}
819
820static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
821 struct sk_buff *vendor_event)
822{
823 u32 i = 0;
824 struct nlattr *rateInfo;
825 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
826 stats->type) ||
827 nla_put(vendor_event,
828 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
829 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
830 nla_put_u32(vendor_event,
831 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
832 stats->capabilities) ||
833 nla_put_u32(vendor_event,
834 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
835 stats->numRate))
836 {
837 hddLog(VOS_TRACE_LEVEL_ERROR,
838 FL("QCA_WLAN_VENDOR_ATTR put fail"));
839 goto error;
840 }
841
842 rateInfo = nla_nest_start(vendor_event,
843 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530844 if(!rateInfo)
845 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530846 for (i = 0; i < stats->numRate; i++)
847 {
848 struct nlattr *rates;
849 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
850 stats->rateStats +
851 (i * sizeof(tSirWifiRateStat)));
852 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530853 if(!rates)
854 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530855
856 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
857 {
858 hddLog(VOS_TRACE_LEVEL_ERROR,
859 FL("QCA_WLAN_VENDOR_ATTR put fail"));
860 return FALSE;
861 }
862 nla_nest_end(vendor_event, rates);
863 }
864 nla_nest_end(vendor_event, rateInfo);
865
866 return TRUE;
867error:
868 return FALSE;
869}
870
871static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
872 struct sk_buff *vendor_event)
873{
874 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
875 stats->ac ) ||
876 nla_put_u32(vendor_event,
877 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
878 stats->txMpdu ) ||
879 nla_put_u32(vendor_event,
880 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
881 stats->rxMpdu ) ||
882 nla_put_u32(vendor_event,
883 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
884 stats->txMcast ) ||
885 nla_put_u32(vendor_event,
886 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
887 stats->rxMcast ) ||
888 nla_put_u32(vendor_event,
889 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
890 stats->rxAmpdu ) ||
891 nla_put_u32(vendor_event,
892 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
893 stats->txAmpdu ) ||
894 nla_put_u32(vendor_event,
895 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
896 stats->mpduLost )||
897 nla_put_u32(vendor_event,
898 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
899 stats->retries ) ||
900 nla_put_u32(vendor_event,
901 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
902 stats->retriesShort ) ||
903 nla_put_u32(vendor_event,
904 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
905 stats->retriesLong ) ||
906 nla_put_u32(vendor_event,
907 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
908 stats->contentionTimeMin ) ||
909 nla_put_u32(vendor_event,
910 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
911 stats->contentionTimeMax ) ||
912 nla_put_u32(vendor_event,
913 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
914 stats->contentionTimeAvg ) ||
915 nla_put_u32(vendor_event,
916 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
917 stats->contentionNumSamples ))
918 {
919 hddLog(VOS_TRACE_LEVEL_ERROR,
920 FL("QCA_WLAN_VENDOR_ATTR put fail") );
921 return FALSE;
922 }
923 return TRUE;
924}
925
926static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
927 struct sk_buff *vendor_event)
928{
Dino Myclec8f3f332014-07-21 16:48:27 +0530929 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530930 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
931 nla_put(vendor_event,
932 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
933 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
934 nla_put_u32(vendor_event,
935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
936 stats->state ) ||
937 nla_put_u32(vendor_event,
938 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
939 stats->roaming ) ||
940 nla_put_u32(vendor_event,
941 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
942 stats->capabilities ) ||
943 nla_put(vendor_event,
944 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
945 strlen(stats->ssid), stats->ssid) ||
946 nla_put(vendor_event,
947 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
948 WNI_CFG_BSSID_LEN, stats->bssid) ||
949 nla_put(vendor_event,
950 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
951 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
952 nla_put(vendor_event,
953 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
954 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
955 )
956 {
957 hddLog(VOS_TRACE_LEVEL_ERROR,
958 FL("QCA_WLAN_VENDOR_ATTR put fail") );
959 return FALSE;
960 }
961 return TRUE;
962}
963
Dino Mycle3b9536d2014-07-09 22:05:24 +0530964static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
965 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530966 struct sk_buff *vendor_event)
967{
968 int i = 0;
969 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530970 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
971 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530972 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530973
Sunil Duttc69bccb2014-05-26 21:30:20 +0530974 if (FALSE == put_wifi_interface_info(
975 &pWifiIfaceStat->info,
976 vendor_event))
977 {
978 hddLog(VOS_TRACE_LEVEL_ERROR,
979 FL("QCA_WLAN_VENDOR_ATTR put fail") );
980 return FALSE;
981
982 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530983 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
984 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
985 if (NULL == pWifiIfaceStatTL)
986 {
987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
988 return FALSE;
989 }
990
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530991 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
992 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
993 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
994 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
995
996 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
997 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
998 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
999 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301000
1001 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1002 {
1003 if (VOS_STATUS_SUCCESS ==
1004 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1005 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1006 {
1007 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1008 * obtained from TL structure
1009 */
1010
1011 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1012 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301013 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1014
Srinivas Dasari98947432014-11-07 19:41:24 +05301015 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1016 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1017 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1018 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1019 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1020 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1021 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1022 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301023
Srinivas Dasari98947432014-11-07 19:41:24 +05301024 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1025 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1026 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1027 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1028 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1029 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1030 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1031 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301032
Srinivas Dasari98947432014-11-07 19:41:24 +05301033 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1034 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1035 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1036 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1037 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1038 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1039 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1040 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301041 }
1042 else
1043 {
1044 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1045 }
1046
Dino Mycle3b9536d2014-07-09 22:05:24 +05301047 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1048 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1049 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1050 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1051 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1052 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1053 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1054 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1055 }
1056 else
1057 {
1058 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1059 }
1060
1061
Sunil Duttc69bccb2014-05-26 21:30:20 +05301062
1063 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301064 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1065 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1066 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301067 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1068 pWifiIfaceStat->beaconRx) ||
1069 nla_put_u32(vendor_event,
1070 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1071 pWifiIfaceStat->mgmtRx) ||
1072 nla_put_u32(vendor_event,
1073 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1074 pWifiIfaceStat->mgmtActionRx) ||
1075 nla_put_u32(vendor_event,
1076 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1077 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301078 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301079 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1080 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301081 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301082 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1083 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301084 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301085 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1086 pWifiIfaceStat->rssiAck))
1087 {
1088 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301089 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1090 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301091 return FALSE;
1092 }
1093
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301094#ifdef FEATURE_EXT_LL_STAT
1095 /*
1096 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1097 * then host should send Leaky AP stats to upper layer,
1098 * otherwise no need to send these stats.
1099 */
1100 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1101 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1102 )
1103 {
1104 hddLog(VOS_TRACE_LEVEL_INFO,
1105 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1106 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1107 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1108 pWifiIfaceStat->leakyApStat.rx_leak_window,
1109 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1110 if (nla_put_u32(vendor_event,
1111 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1112 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1113 nla_put_u32(vendor_event,
1114 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1115 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1116 nla_put_u32(vendor_event,
1117 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1118 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1119 nla_put_u64(vendor_event,
1120 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1121 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1122 {
1123 hddLog(VOS_TRACE_LEVEL_ERROR,
1124 FL("EXT_LL_STAT put fail"));
1125 vos_mem_free(pWifiIfaceStatTL);
1126 return FALSE;
1127 }
1128 }
1129#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301130 wmmInfo = nla_nest_start(vendor_event,
1131 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301132 if(!wmmInfo)
1133 {
1134 vos_mem_free(pWifiIfaceStatTL);
1135 return FALSE;
1136 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301137 for (i = 0; i < WIFI_AC_MAX; i++)
1138 {
1139 struct nlattr *wmmStats;
1140 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301141 if(!wmmStats)
1142 {
1143 vos_mem_free(pWifiIfaceStatTL);
1144 return FALSE;
1145 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301146 if (FALSE == put_wifi_wmm_ac_stat(
1147 &pWifiIfaceStat->AccessclassStats[i],
1148 vendor_event))
1149 {
1150 hddLog(VOS_TRACE_LEVEL_ERROR,
1151 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301152 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301153 return FALSE;
1154 }
1155
1156 nla_nest_end(vendor_event, wmmStats);
1157 }
1158 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301159 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301160 return TRUE;
1161}
1162
1163static tSirWifiInterfaceMode
1164 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1165{
1166 switch (deviceMode)
1167 {
1168 case WLAN_HDD_INFRA_STATION:
1169 return WIFI_INTERFACE_STA;
1170 case WLAN_HDD_SOFTAP:
1171 return WIFI_INTERFACE_SOFTAP;
1172 case WLAN_HDD_P2P_CLIENT:
1173 return WIFI_INTERFACE_P2P_CLIENT;
1174 case WLAN_HDD_P2P_GO:
1175 return WIFI_INTERFACE_P2P_GO;
1176 case WLAN_HDD_IBSS:
1177 return WIFI_INTERFACE_IBSS;
1178 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301179 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301180 }
1181}
1182
1183static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1184 tpSirWifiInterfaceInfo pInfo)
1185{
1186 v_U8_t *staMac = NULL;
1187 hdd_station_ctx_t *pHddStaCtx;
1188 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1189 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1190
1191 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1192
1193 vos_mem_copy(pInfo->macAddr,
1194 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1195
1196 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1197 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1198 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1199 {
1200 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1201 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1202 {
1203 pInfo->state = WIFI_DISCONNECTED;
1204 }
1205 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1206 {
1207 hddLog(VOS_TRACE_LEVEL_ERROR,
1208 "%s: Session ID %d, Connection is in progress", __func__,
1209 pAdapter->sessionId);
1210 pInfo->state = WIFI_ASSOCIATING;
1211 }
1212 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1213 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1214 {
1215 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1216 hddLog(VOS_TRACE_LEVEL_ERROR,
1217 "%s: client " MAC_ADDRESS_STR
1218 " is in the middle of WPS/EAPOL exchange.", __func__,
1219 MAC_ADDR_ARRAY(staMac));
1220 pInfo->state = WIFI_AUTHENTICATING;
1221 }
1222 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1223 {
1224 pInfo->state = WIFI_ASSOCIATED;
1225 vos_mem_copy(pInfo->bssid,
1226 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1227 vos_mem_copy(pInfo->ssid,
1228 pHddStaCtx->conn_info.SSID.SSID.ssId,
1229 pHddStaCtx->conn_info.SSID.SSID.length);
1230 //NULL Terminate the string.
1231 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1232 }
1233 }
1234 vos_mem_copy(pInfo->countryStr,
1235 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1236
1237 vos_mem_copy(pInfo->apCountryStr,
1238 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1239
1240 return TRUE;
1241}
1242
1243/*
1244 * hdd_link_layer_process_peer_stats () - This function is called after
1245 * receiving Link Layer Peer statistics from FW.This function converts
1246 * the firmware data to the NL data and sends the same to the kernel/upper
1247 * layers.
1248 */
1249static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1250 v_VOID_t *pData)
1251{
1252 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301253 tpSirWifiPeerStat pWifiPeerStat;
1254 tpSirWifiPeerInfo pWifiPeerInfo;
1255 struct nlattr *peerInfo;
1256 struct sk_buff *vendor_event;
1257 int status, i;
1258
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301259 ENTER();
1260
Sunil Duttc69bccb2014-05-26 21:30:20 +05301261 status = wlan_hdd_validate_context(pHddCtx);
1262 if (0 != status)
1263 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301264 return;
1265 }
1266
1267 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1268
1269 hddLog(VOS_TRACE_LEVEL_INFO,
1270 "LL_STATS_PEER_ALL : numPeers %u",
1271 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301272 /*
1273 * Allocate a size of 4096 for the peer stats comprising
1274 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1275 * sizeof (tSirWifiRateStat).Each field is put with an
1276 * NL attribute.The size of 4096 is considered assuming
1277 * that number of rates shall not exceed beyond 50 with
1278 * the sizeof (tSirWifiRateStat) being 32.
1279 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301280 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1281 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301282 if (!vendor_event)
1283 {
1284 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301285 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301286 __func__);
1287 return;
1288 }
1289 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301290 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1291 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1292 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301293 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1294 pWifiPeerStat->numPeers))
1295 {
1296 hddLog(VOS_TRACE_LEVEL_ERROR,
1297 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1298 kfree_skb(vendor_event);
1299 return;
1300 }
1301
1302 peerInfo = nla_nest_start(vendor_event,
1303 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301304 if(!peerInfo)
1305 {
1306 hddLog(VOS_TRACE_LEVEL_ERROR,
1307 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1308 __func__);
1309 kfree_skb(vendor_event);
1310 return;
1311 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301312
1313 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1314 pWifiPeerStat->peerInfo);
1315
1316 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1317 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301318 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301319 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301320
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301321 if(!peers)
1322 {
1323 hddLog(VOS_TRACE_LEVEL_ERROR,
1324 "%s: peer stats put fail",
1325 __func__);
1326 kfree_skb(vendor_event);
1327 return;
1328 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301329 if (FALSE == put_wifi_peer_info(
1330 pWifiPeerInfo, vendor_event))
1331 {
1332 hddLog(VOS_TRACE_LEVEL_ERROR,
1333 "%s: put_wifi_peer_info put fail", __func__);
1334 kfree_skb(vendor_event);
1335 return;
1336 }
1337
1338 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1339 pWifiPeerStat->peerInfo +
1340 (i * sizeof(tSirWifiPeerInfo)) +
1341 (numRate * sizeof (tSirWifiRateStat)));
1342 nla_nest_end(vendor_event, peers);
1343 }
1344 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301345 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301346 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301347}
1348
1349/*
1350 * hdd_link_layer_process_iface_stats () - This function is called after
1351 * receiving Link Layer Interface statistics from FW.This function converts
1352 * the firmware data to the NL data and sends the same to the kernel/upper
1353 * layers.
1354 */
1355static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1356 v_VOID_t *pData)
1357{
1358 tpSirWifiIfaceStat pWifiIfaceStat;
1359 struct sk_buff *vendor_event;
1360 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1361 int status;
1362
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301363 ENTER();
1364
Sunil Duttc69bccb2014-05-26 21:30:20 +05301365 status = wlan_hdd_validate_context(pHddCtx);
1366 if (0 != status)
1367 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301368 return;
1369 }
1370 /*
1371 * Allocate a size of 4096 for the interface stats comprising
1372 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1373 * assuming that all these fit with in the limit.Please take
1374 * a call on the limit based on the data requirements on
1375 * interface statistics.
1376 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301377 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1378 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301379 if (!vendor_event)
1380 {
1381 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301382 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301383 return;
1384 }
1385
1386 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1387
Dino Mycle3b9536d2014-07-09 22:05:24 +05301388
1389 if (FALSE == hdd_get_interface_info( pAdapter,
1390 &pWifiIfaceStat->info))
1391 {
1392 hddLog(VOS_TRACE_LEVEL_ERROR,
1393 FL("hdd_get_interface_info get fail") );
1394 kfree_skb(vendor_event);
1395 return;
1396 }
1397
1398 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1399 vendor_event))
1400 {
1401 hddLog(VOS_TRACE_LEVEL_ERROR,
1402 FL("put_wifi_iface_stats fail") );
1403 kfree_skb(vendor_event);
1404 return;
1405 }
1406
Sunil Duttc69bccb2014-05-26 21:30:20 +05301407 hddLog(VOS_TRACE_LEVEL_INFO,
1408 "WMI_LINK_STATS_IFACE Data");
1409
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301410 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301411
1412 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301413}
1414
1415/*
1416 * hdd_link_layer_process_radio_stats () - This function is called after
1417 * receiving Link Layer Radio statistics from FW.This function converts
1418 * the firmware data to the NL data and sends the same to the kernel/upper
1419 * layers.
1420 */
1421static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1422 v_VOID_t *pData)
1423{
1424 int status, i;
1425 tpSirWifiRadioStat pWifiRadioStat;
1426 tpSirWifiChannelStats pWifiChannelStats;
1427 struct sk_buff *vendor_event;
1428 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1429 struct nlattr *chList;
1430
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301431 ENTER();
1432
Sunil Duttc69bccb2014-05-26 21:30:20 +05301433 status = wlan_hdd_validate_context(pHddCtx);
1434 if (0 != status)
1435 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301436 return;
1437 }
1438 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1439
1440 hddLog(VOS_TRACE_LEVEL_INFO,
1441 "LL_STATS_RADIO"
1442 " radio is %d onTime is %u "
1443 " txTime is %u rxTime is %u "
1444 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301445 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301446 " onTimePnoScan is %u onTimeHs20 is %u "
1447 " numChannels is %u",
1448 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1449 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1450 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301451 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301452 pWifiRadioStat->onTimeRoamScan,
1453 pWifiRadioStat->onTimePnoScan,
1454 pWifiRadioStat->onTimeHs20,
1455 pWifiRadioStat->numChannels);
1456 /*
1457 * Allocate a size of 4096 for the Radio stats comprising
1458 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1459 * (tSirWifiChannelStats).Each channel data is put with an
1460 * NL attribute.The size of 4096 is considered assuming that
1461 * number of channels shall not exceed beyond 60 with the
1462 * sizeof (tSirWifiChannelStats) being 24 bytes.
1463 */
1464
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301465 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1466 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301467 if (!vendor_event)
1468 {
1469 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301470 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301471 return;
1472 }
1473
1474 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301475 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1476 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1477 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301478 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1479 pWifiRadioStat->radio) ||
1480 nla_put_u32(vendor_event,
1481 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1482 pWifiRadioStat->onTime) ||
1483 nla_put_u32(vendor_event,
1484 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1485 pWifiRadioStat->txTime) ||
1486 nla_put_u32(vendor_event,
1487 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1488 pWifiRadioStat->rxTime) ||
1489 nla_put_u32(vendor_event,
1490 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1491 pWifiRadioStat->onTimeScan) ||
1492 nla_put_u32(vendor_event,
1493 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1494 pWifiRadioStat->onTimeNbd) ||
1495 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301496 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1497 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301498 nla_put_u32(vendor_event,
1499 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1500 pWifiRadioStat->onTimeRoamScan) ||
1501 nla_put_u32(vendor_event,
1502 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1503 pWifiRadioStat->onTimePnoScan) ||
1504 nla_put_u32(vendor_event,
1505 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1506 pWifiRadioStat->onTimeHs20) ||
1507 nla_put_u32(vendor_event,
1508 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1509 pWifiRadioStat->numChannels))
1510 {
1511 hddLog(VOS_TRACE_LEVEL_ERROR,
1512 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1513 kfree_skb(vendor_event);
1514 return ;
1515 }
1516
1517 chList = nla_nest_start(vendor_event,
1518 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301519 if(!chList)
1520 {
1521 hddLog(VOS_TRACE_LEVEL_ERROR,
1522 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1523 __func__);
1524 kfree_skb(vendor_event);
1525 return;
1526 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301527 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1528 {
1529 struct nlattr *chInfo;
1530
1531 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1532 pWifiRadioStat->channels +
1533 (i * sizeof(tSirWifiChannelStats)));
1534
Sunil Duttc69bccb2014-05-26 21:30:20 +05301535 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301536 if(!chInfo)
1537 {
1538 hddLog(VOS_TRACE_LEVEL_ERROR,
1539 "%s: failed to put chInfo",
1540 __func__);
1541 kfree_skb(vendor_event);
1542 return;
1543 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301544
1545 if (nla_put_u32(vendor_event,
1546 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1547 pWifiChannelStats->channel.width) ||
1548 nla_put_u32(vendor_event,
1549 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1550 pWifiChannelStats->channel.centerFreq) ||
1551 nla_put_u32(vendor_event,
1552 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1553 pWifiChannelStats->channel.centerFreq0) ||
1554 nla_put_u32(vendor_event,
1555 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1556 pWifiChannelStats->channel.centerFreq1) ||
1557 nla_put_u32(vendor_event,
1558 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1559 pWifiChannelStats->onTime) ||
1560 nla_put_u32(vendor_event,
1561 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1562 pWifiChannelStats->ccaBusyTime))
1563 {
1564 hddLog(VOS_TRACE_LEVEL_ERROR,
1565 FL("cfg80211_vendor_event_alloc failed") );
1566 kfree_skb(vendor_event);
1567 return ;
1568 }
1569 nla_nest_end(vendor_event, chInfo);
1570 }
1571 nla_nest_end(vendor_event, chList);
1572
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301573 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301574
1575 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301576 return;
1577}
1578
1579/*
1580 * hdd_link_layer_stats_ind_callback () - This function is called after
1581 * receiving Link Layer indications from FW.This callback converts the firmware
1582 * data to the NL data and send the same to the kernel/upper layers.
1583 */
1584static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1585 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301586 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301587{
Dino Mycled3d50022014-07-07 12:58:25 +05301588 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1589 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301590 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301591 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301592 int status;
1593
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301594 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301595
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301596 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301597 if (0 != status)
1598 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301599 return;
1600 }
1601
Dino Mycled3d50022014-07-07 12:58:25 +05301602 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1603 if (NULL == pAdapter)
1604 {
1605 hddLog(VOS_TRACE_LEVEL_ERROR,
1606 FL(" MAC address %pM does not exist with host"),
1607 macAddr);
1608 return;
1609 }
1610
Sunil Duttc69bccb2014-05-26 21:30:20 +05301611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301612 "%s: Interface: %s LLStats indType: %d", __func__,
1613 pAdapter->dev->name, indType);
1614
Sunil Duttc69bccb2014-05-26 21:30:20 +05301615 switch (indType)
1616 {
1617 case SIR_HAL_LL_STATS_RESULTS_RSP:
1618 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301619 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301620 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1621 "respId = %u, moreResultToFollow = %u",
1622 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1623 macAddr, linkLayerStatsResults->respId,
1624 linkLayerStatsResults->moreResultToFollow);
1625
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301626 spin_lock(&hdd_context_lock);
1627 context = &pHddCtx->ll_stats_context;
1628 /* validate response received from target */
1629 if ((context->request_id != linkLayerStatsResults->respId) ||
1630 !(context->request_bitmap & linkLayerStatsResults->paramId))
1631 {
1632 spin_unlock(&hdd_context_lock);
1633 hddLog(LOGE,
1634 FL("Error : Request id %d response id %d request bitmap 0x%x"
1635 "response bitmap 0x%x"),
1636 context->request_id, linkLayerStatsResults->respId,
1637 context->request_bitmap, linkLayerStatsResults->paramId);
1638 return;
1639 }
1640 spin_unlock(&hdd_context_lock);
1641
Sunil Duttc69bccb2014-05-26 21:30:20 +05301642 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1643 {
1644 hdd_link_layer_process_radio_stats(pAdapter,
1645 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301646 spin_lock(&hdd_context_lock);
1647 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1648 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301649 }
1650 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1651 {
1652 hdd_link_layer_process_iface_stats(pAdapter,
1653 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301654 spin_lock(&hdd_context_lock);
1655 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1656 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301657 }
1658 else if ( linkLayerStatsResults->paramId &
1659 WMI_LINK_STATS_ALL_PEER )
1660 {
1661 hdd_link_layer_process_peer_stats(pAdapter,
1662 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301663 spin_lock(&hdd_context_lock);
1664 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1665 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301666 } /* WMI_LINK_STATS_ALL_PEER */
1667 else
1668 {
1669 hddLog(VOS_TRACE_LEVEL_ERROR,
1670 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1671 }
1672
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301673 spin_lock(&hdd_context_lock);
1674 /* complete response event if all requests are completed */
1675 if (0 == context->request_bitmap)
1676 complete(&context->response_event);
1677 spin_unlock(&hdd_context_lock);
1678
Sunil Duttc69bccb2014-05-26 21:30:20 +05301679 break;
1680 }
1681 default:
1682 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1683 break;
1684 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301685
1686 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301687 return;
1688}
1689
1690const struct
1691nla_policy
1692qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1693{
1694 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1695 { .type = NLA_U32 },
1696 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1697 { .type = NLA_U32 },
1698};
1699
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301700static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1701 struct wireless_dev *wdev,
1702 const void *data,
1703 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301704{
1705 int status;
1706 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301707 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301708 struct net_device *dev = wdev->netdev;
1709 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1710 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1711
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301712 ENTER();
1713
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714 status = wlan_hdd_validate_context(pHddCtx);
1715 if (0 != status)
1716 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301717 return -EINVAL;
1718 }
1719
1720 if (NULL == pAdapter)
1721 {
1722 hddLog(VOS_TRACE_LEVEL_ERROR,
1723 FL("HDD adapter is Null"));
1724 return -ENODEV;
1725 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301726 /* check the LLStats Capability */
1727 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1728 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1729 {
1730 hddLog(VOS_TRACE_LEVEL_ERROR,
1731 FL("Link Layer Statistics not supported by Firmware"));
1732 return -EINVAL;
1733 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301734
1735 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1736 (struct nlattr *)data,
1737 data_len, qca_wlan_vendor_ll_set_policy))
1738 {
1739 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1740 return -EINVAL;
1741 }
1742 if (!tb_vendor
1743 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1744 {
1745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1746 return -EINVAL;
1747 }
1748 if (!tb_vendor[
1749 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1750 {
1751 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1752 return -EINVAL;
1753 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301754 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301755 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301756
Dino Mycledf0a5d92014-07-04 09:41:55 +05301757 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301758 nla_get_u32(
1759 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1760
Dino Mycledf0a5d92014-07-04 09:41:55 +05301761 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301762 nla_get_u32(
1763 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1764
Dino Mycled3d50022014-07-07 12:58:25 +05301765 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1766 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301767
1768
1769 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301770 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1771 "Statistics Gathering = %d ",
1772 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1773 linkLayerStatsSetReq.mpduSizeThreshold,
1774 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301775
1776 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1777 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301778 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301779 {
1780 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1781 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301782 return -EINVAL;
1783
1784 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301785
Sunil Duttc69bccb2014-05-26 21:30:20 +05301786 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301787 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301788 {
1789 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1790 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301791 return -EINVAL;
1792 }
1793
1794 pAdapter->isLinkLayerStatsSet = 1;
1795
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301796 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301797 return 0;
1798}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301799static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1800 struct wireless_dev *wdev,
1801 const void *data,
1802 int data_len)
1803{
1804 int ret = 0;
1805
1806 vos_ssr_protect(__func__);
1807 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1808 vos_ssr_unprotect(__func__);
1809
1810 return ret;
1811}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301812
1813const struct
1814nla_policy
1815qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1816{
1817 /* Unsigned 32bit value provided by the caller issuing the GET stats
1818 * command. When reporting
1819 * the stats results, the driver uses the same value to indicate
1820 * which GET request the results
1821 * correspond to.
1822 */
1823 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1824
1825 /* Unsigned 32bit value . bit mask to identify what statistics are
1826 requested for retrieval */
1827 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1828};
1829
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301830static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1831 struct wireless_dev *wdev,
1832 const void *data,
1833 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301834{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301835 unsigned long rc;
1836 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301837 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1838 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301839 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301840 struct net_device *dev = wdev->netdev;
1841 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301842 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301843 int status;
1844
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301845 ENTER();
1846
Sunil Duttc69bccb2014-05-26 21:30:20 +05301847 status = wlan_hdd_validate_context(pHddCtx);
1848 if (0 != status)
1849 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301850 return -EINVAL ;
1851 }
1852
1853 if (NULL == pAdapter)
1854 {
1855 hddLog(VOS_TRACE_LEVEL_FATAL,
1856 "%s: HDD adapter is Null", __func__);
1857 return -ENODEV;
1858 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301859
1860 if (pHddStaCtx == NULL)
1861 {
1862 hddLog(VOS_TRACE_LEVEL_FATAL,
1863 "%s: HddStaCtx is Null", __func__);
1864 return -ENODEV;
1865 }
1866
Dino Mycledf0a5d92014-07-04 09:41:55 +05301867 /* check the LLStats Capability */
1868 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1869 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1870 {
1871 hddLog(VOS_TRACE_LEVEL_ERROR,
1872 FL("Link Layer Statistics not supported by Firmware"));
1873 return -EINVAL;
1874 }
1875
Sunil Duttc69bccb2014-05-26 21:30:20 +05301876
1877 if (!pAdapter->isLinkLayerStatsSet)
1878 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05301879 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301880 "%s: isLinkLayerStatsSet : %d",
1881 __func__, pAdapter->isLinkLayerStatsSet);
1882 return -EINVAL;
1883 }
1884
Mukul Sharma10313ba2015-07-29 19:14:39 +05301885 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1886 {
1887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1888 "%s: Roaming in progress, so unable to proceed this request", __func__);
1889 return -EBUSY;
1890 }
1891
Sunil Duttc69bccb2014-05-26 21:30:20 +05301892 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1893 (struct nlattr *)data,
1894 data_len, qca_wlan_vendor_ll_get_policy))
1895 {
1896 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1897 return -EINVAL;
1898 }
1899
1900 if (!tb_vendor
1901 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1902 {
1903 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1904 return -EINVAL;
1905 }
1906
1907 if (!tb_vendor
1908 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1909 {
1910 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1911 return -EINVAL;
1912 }
1913
Sunil Duttc69bccb2014-05-26 21:30:20 +05301914
Dino Mycledf0a5d92014-07-04 09:41:55 +05301915 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 nla_get_u32( tb_vendor[
1917 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301918 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919 nla_get_u32( tb_vendor[
1920 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1921
Dino Mycled3d50022014-07-07 12:58:25 +05301922 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1923 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301924
1925 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301926 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1927 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301928 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301929
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301930 spin_lock(&hdd_context_lock);
1931 context = &pHddCtx->ll_stats_context;
1932 context->request_id = linkLayerStatsGetReq.reqId;
1933 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1934 INIT_COMPLETION(context->response_event);
1935 spin_unlock(&hdd_context_lock);
1936
Sunil Duttc69bccb2014-05-26 21:30:20 +05301937 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301938 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301939 {
1940 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1941 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301942 return -EINVAL;
1943 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301944
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301945 rc = wait_for_completion_timeout(&context->response_event,
1946 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1947 if (!rc)
1948 {
1949 hddLog(LOGE,
1950 FL("Target response timed out request id %d request bitmap 0x%x"),
1951 context->request_id, context->request_bitmap);
1952 return -ETIMEDOUT;
1953 }
1954
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301955 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301956 return 0;
1957}
1958
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301959static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1960 struct wireless_dev *wdev,
1961 const void *data,
1962 int data_len)
1963{
1964 int ret = 0;
1965
1966 vos_ssr_protect(__func__);
1967 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1968 vos_ssr_unprotect(__func__);
1969
1970 return ret;
1971}
1972
Sunil Duttc69bccb2014-05-26 21:30:20 +05301973const struct
1974nla_policy
1975qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1976{
1977 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1978 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1979 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1980 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1981};
1982
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301983static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1984 struct wireless_dev *wdev,
1985 const void *data,
1986 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301987{
1988 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1989 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301990 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301991 struct net_device *dev = wdev->netdev;
1992 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1993 u32 statsClearReqMask;
1994 u8 stopReq;
1995 int status;
1996
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301997 ENTER();
1998
Sunil Duttc69bccb2014-05-26 21:30:20 +05301999 status = wlan_hdd_validate_context(pHddCtx);
2000 if (0 != status)
2001 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302002 return -EINVAL;
2003 }
2004
2005 if (NULL == pAdapter)
2006 {
2007 hddLog(VOS_TRACE_LEVEL_FATAL,
2008 "%s: HDD adapter is Null", __func__);
2009 return -ENODEV;
2010 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302011 /* check the LLStats Capability */
2012 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2013 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2014 {
2015 hddLog(VOS_TRACE_LEVEL_ERROR,
2016 FL("Enable LLStats Capability"));
2017 return -EINVAL;
2018 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302019
2020 if (!pAdapter->isLinkLayerStatsSet)
2021 {
2022 hddLog(VOS_TRACE_LEVEL_FATAL,
2023 "%s: isLinkLayerStatsSet : %d",
2024 __func__, pAdapter->isLinkLayerStatsSet);
2025 return -EINVAL;
2026 }
2027
2028 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2029 (struct nlattr *)data,
2030 data_len, qca_wlan_vendor_ll_clr_policy))
2031 {
2032 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2033 return -EINVAL;
2034 }
2035
2036 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2037
2038 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2039 {
2040 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2041 return -EINVAL;
2042
2043 }
2044
Sunil Duttc69bccb2014-05-26 21:30:20 +05302045
Dino Mycledf0a5d92014-07-04 09:41:55 +05302046 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302047 nla_get_u32(
2048 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2049
Dino Mycledf0a5d92014-07-04 09:41:55 +05302050 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302051 nla_get_u8(
2052 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2053
2054 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302055 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302056
Dino Mycled3d50022014-07-07 12:58:25 +05302057 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2058 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302059
2060 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302061 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2062 "statsClearReqMask = 0x%X, stopReq = %d",
2063 linkLayerStatsClearReq.reqId,
2064 linkLayerStatsClearReq.macAddr,
2065 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302066 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302067
2068 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302069 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302070 {
2071 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302072 hdd_station_ctx_t *pHddStaCtx;
2073
2074 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2075 if (VOS_STATUS_SUCCESS !=
2076 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2077 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2078 {
2079 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2080 "WLANTL_ClearInterfaceStats Failed", __func__);
2081 return -EINVAL;
2082 }
2083 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2084 (statsClearReqMask & WIFI_STATS_IFACE)) {
2085 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2086 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2087 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2088 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2089 }
2090
Sunil Duttc69bccb2014-05-26 21:30:20 +05302091 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2092 2 * sizeof(u32) +
2093 NLMSG_HDRLEN);
2094
2095 if (temp_skbuff != NULL)
2096 {
2097
2098 if (nla_put_u32(temp_skbuff,
2099 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2100 statsClearReqMask) ||
2101 nla_put_u32(temp_skbuff,
2102 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2103 stopReq))
2104 {
2105 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2106 kfree_skb(temp_skbuff);
2107 return -EINVAL;
2108 }
2109 /* If the ask is to stop the stats collection as part of clear
2110 * (stopReq = 1) , ensure that no further requests of get
2111 * go to the firmware by having isLinkLayerStatsSet set to 0.
2112 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302113 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302114 * case the firmware is just asked to clear the statistics.
2115 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302116 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302117 pAdapter->isLinkLayerStatsSet = 0;
2118 return cfg80211_vendor_cmd_reply(temp_skbuff);
2119 }
2120 return -ENOMEM;
2121 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302122
2123 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302124 return -EINVAL;
2125}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302126static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2127 struct wireless_dev *wdev,
2128 const void *data,
2129 int data_len)
2130{
2131 int ret = 0;
2132
2133 vos_ssr_protect(__func__);
2134 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2135 vos_ssr_unprotect(__func__);
2136
2137 return ret;
2138
2139
2140}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2142
Dino Mycle6fb96c12014-06-10 11:52:40 +05302143#ifdef WLAN_FEATURE_EXTSCAN
2144static const struct nla_policy
2145wlan_hdd_extscan_config_policy
2146 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2147{
2148 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2149 { .type = NLA_U32 },
2150 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2151 { .type = NLA_U32 },
2152 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2153 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2154 { .type = NLA_U32 },
2155 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2157
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2159 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2161 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2162 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302163 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2164 { .type = NLA_U32 },
2165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2166 { .type = NLA_U32 },
2167 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2168 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2170 { .type = NLA_U32 },
2171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2172 { .type = NLA_U32 },
2173 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2174 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2176 { .type = NLA_U8 },
2177 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302178 { .type = NLA_U8 },
2179 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2180 { .type = NLA_U8 },
2181 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2182 { .type = NLA_U8 },
2183
2184 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2185 { .type = NLA_U32 },
2186 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2187 { .type = NLA_UNSPEC },
2188 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2189 { .type = NLA_S32 },
2190 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2191 { .type = NLA_S32 },
2192 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2193 { .type = NLA_U32 },
2194 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2195 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302196 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2197 { .type = NLA_U32 },
2198 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2199 { .type = NLA_BINARY,
2200 .len = IEEE80211_MAX_SSID_LEN + 1 },
2201 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302202 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302203 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2204 { .type = NLA_U32 },
2205 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2206 { .type = NLA_U8 },
2207 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2208 { .type = NLA_S32 },
2209 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2210 { .type = NLA_S32 },
2211 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2212 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302213};
2214
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302215/**
2216 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2217 * @ctx: hdd global context
2218 * @data: capabilities data
2219 *
2220 * Return: none
2221 */
2222static void
2223wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302224{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302225 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302226 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302227 tSirEXTScanCapabilitiesEvent *data =
2228 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302229
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302230 ENTER();
2231
2232 if (wlan_hdd_validate_context(pHddCtx))
2233 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302234 return;
2235 }
2236
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302237 if (!pMsg)
2238 {
2239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2240 return;
2241 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302242
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302243 vos_spin_lock_acquire(&hdd_context_lock);
2244
2245 context = &pHddCtx->ext_scan_context;
2246 /* validate response received from target*/
2247 if (context->request_id != data->requestId)
2248 {
2249 vos_spin_lock_release(&hdd_context_lock);
2250 hddLog(LOGE,
2251 FL("Target response id did not match: request_id %d resposne_id %d"),
2252 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302253 return;
2254 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302255 else
2256 {
2257 context->capability_response = *data;
2258 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302259 }
2260
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302261 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302262
Dino Mycle6fb96c12014-06-10 11:52:40 +05302263 return;
2264}
2265
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302266/*
2267 * define short names for the global vendor params
2268 * used by wlan_hdd_send_ext_scan_capability()
2269 */
2270#define PARAM_REQUEST_ID \
2271 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2272#define PARAM_STATUS \
2273 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2274#define MAX_SCAN_CACHE_SIZE \
2275 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2276#define MAX_SCAN_BUCKETS \
2277 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2278#define MAX_AP_CACHE_PER_SCAN \
2279 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2280#define MAX_RSSI_SAMPLE_SIZE \
2281 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2282#define MAX_SCAN_RPT_THRHOLD \
2283 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2284#define MAX_HOTLIST_BSSIDS \
2285 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2286#define MAX_BSSID_HISTORY_ENTRIES \
2287 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2288#define MAX_HOTLIST_SSIDS \
2289 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302290#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2291 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302292
2293static int wlan_hdd_send_ext_scan_capability(void *ctx)
2294{
2295 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2296 struct sk_buff *skb = NULL;
2297 int ret;
2298 tSirEXTScanCapabilitiesEvent *data;
2299 tANI_U32 nl_buf_len;
2300
2301 ret = wlan_hdd_validate_context(pHddCtx);
2302 if (0 != ret)
2303 {
2304 return ret;
2305 }
2306
2307 data = &(pHddCtx->ext_scan_context.capability_response);
2308
2309 nl_buf_len = NLMSG_HDRLEN;
2310 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2311 (sizeof(data->status) + NLA_HDRLEN) +
2312 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2313 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2314 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2315 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2316 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2317 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2318 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2319 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2320
2321 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2322
2323 if (!skb)
2324 {
2325 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2326 return -ENOMEM;
2327 }
2328
2329 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2330 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2331 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2332 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2333 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2334 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2335 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2336 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2337
2338 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2339 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2340 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2341 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2342 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2343 data->maxApPerScan) ||
2344 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2345 data->maxRssiSampleSize) ||
2346 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2347 data->maxScanReportingThreshold) ||
2348 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2349 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2350 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302351 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2352 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302353 {
2354 hddLog(LOGE, FL("nla put fail"));
2355 goto nla_put_failure;
2356 }
2357
2358 cfg80211_vendor_cmd_reply(skb);
2359 return 0;
2360
2361nla_put_failure:
2362 kfree_skb(skb);
2363 return -EINVAL;;
2364}
2365
2366/*
2367 * done with short names for the global vendor params
2368 * used by wlan_hdd_send_ext_scan_capability()
2369 */
2370#undef PARAM_REQUEST_ID
2371#undef PARAM_STATUS
2372#undef MAX_SCAN_CACHE_SIZE
2373#undef MAX_SCAN_BUCKETS
2374#undef MAX_AP_CACHE_PER_SCAN
2375#undef MAX_RSSI_SAMPLE_SIZE
2376#undef MAX_SCAN_RPT_THRHOLD
2377#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302378#undef MAX_BSSID_HISTORY_ENTRIES
2379#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302380
2381static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2382{
2383 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2384 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302385 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302386 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302387
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302388 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302389
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302390 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302391 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302392
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302393 if (!pMsg)
2394 {
2395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302396 return;
2397 }
2398
Dino Mycle6fb96c12014-06-10 11:52:40 +05302399 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2400 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2401
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302402 context = &pHddCtx->ext_scan_context;
2403 spin_lock(&hdd_context_lock);
2404 if (context->request_id == pData->requestId) {
2405 context->response_status = pData->status ? -EINVAL : 0;
2406 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302407 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302408 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302409
2410 /*
2411 * Store the Request ID for comparing with the requestID obtained
2412 * in other requests.HDD shall return a failure is the extscan_stop
2413 * request is issued with a different requestId as that of the
2414 * extscan_start request. Also, This requestId shall be used while
2415 * indicating the full scan results to the upper layers.
2416 * The requestId is stored with the assumption that the firmware
2417 * shall return the ext scan start request's requestId in ext scan
2418 * start response.
2419 */
2420 if (pData->status == 0)
2421 pMac->sme.extScanStartReqId = pData->requestId;
2422
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302423 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302424 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302425}
2426
2427
2428static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2429{
2430 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2431 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302432 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302433
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302434 ENTER();
2435
2436 if (wlan_hdd_validate_context(pHddCtx)){
2437 return;
2438 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302439
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302440 if (!pMsg)
2441 {
2442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302443 return;
2444 }
2445
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302446 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2447 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302448
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302449 context = &pHddCtx->ext_scan_context;
2450 spin_lock(&hdd_context_lock);
2451 if (context->request_id == pData->requestId) {
2452 context->response_status = pData->status ? -EINVAL : 0;
2453 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302454 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302455 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302456
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302457 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302458 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302459}
2460
Dino Mycle6fb96c12014-06-10 11:52:40 +05302461static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2462 void *pMsg)
2463{
2464 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302465 tpSirEXTScanSetBssidHotListRspParams pData =
2466 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302467 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302468
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302469 ENTER();
2470
2471 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302472 return;
2473 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302474
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302475 if (!pMsg)
2476 {
2477 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2478 return;
2479 }
2480
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302481 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2482 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302483
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302484 context = &pHddCtx->ext_scan_context;
2485 spin_lock(&hdd_context_lock);
2486 if (context->request_id == pData->requestId) {
2487 context->response_status = pData->status ? -EINVAL : 0;
2488 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302489 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302490 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302491
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302492 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302493 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302494}
2495
2496static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2497 void *pMsg)
2498{
2499 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302500 tpSirEXTScanResetBssidHotlistRspParams pData =
2501 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302502 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302503
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302504 ENTER();
2505
2506 if (wlan_hdd_validate_context(pHddCtx)) {
2507 return;
2508 }
2509 if (!pMsg)
2510 {
2511 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302512 return;
2513 }
2514
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302515 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2516 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302517
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302518 context = &pHddCtx->ext_scan_context;
2519 spin_lock(&hdd_context_lock);
2520 if (context->request_id == pData->requestId) {
2521 context->response_status = pData->status ? -EINVAL : 0;
2522 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302523 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302524 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302525
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302526 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302527 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302528}
2529
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302530static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2531 void *pMsg)
2532{
2533 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2534 tpSirEXTScanSetSsidHotListRspParams pData =
2535 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2536 struct hdd_ext_scan_context *context;
2537
2538 if (wlan_hdd_validate_context(pHddCtx)){
2539 return;
2540 }
2541
2542 if (!pMsg)
2543 {
2544 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2545 return;
2546 }
2547
2548 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2549 pData->status);
2550
2551 context = &pHddCtx->ext_scan_context;
2552 spin_lock(&hdd_context_lock);
2553 if (context->request_id == pData->requestId) {
2554 context->response_status = pData->status ? -EINVAL : 0;
2555 complete(&context->response_event);
2556 }
2557 spin_unlock(&hdd_context_lock);
2558
2559 return;
2560}
2561
2562static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2563 void *pMsg)
2564{
2565 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2566 tpSirEXTScanResetSsidHotlistRspParams pData =
2567 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2568 struct hdd_ext_scan_context *context;
2569
2570 if (wlan_hdd_validate_context(pHddCtx)) {
2571 return;
2572 }
2573 if (!pMsg)
2574 {
2575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2576 return;
2577 }
2578
2579 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2580 pData->status);
2581
2582 context = &pHddCtx->ext_scan_context;
2583 spin_lock(&hdd_context_lock);
2584 if (context->request_id == pData->requestId) {
2585 context->response_status = pData->status ? -EINVAL : 0;
2586 complete(&context->response_event);
2587 }
2588 spin_unlock(&hdd_context_lock);
2589
2590 return;
2591}
2592
2593
Dino Mycle6fb96c12014-06-10 11:52:40 +05302594static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2595 void *pMsg)
2596{
2597 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2598 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302599 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302600 tANI_S32 totalResults;
2601 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302602 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2603 struct hdd_ext_scan_context *context;
2604 bool ignore_cached_results = false;
2605 tExtscanCachedScanResult *result;
2606 struct nlattr *nla_results;
2607 tANI_U16 ieLength= 0;
2608 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302609
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302610 ENTER();
2611
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302612 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302613 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302614
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302615 if (!pMsg)
2616 {
2617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2618 return;
2619 }
2620
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302621 spin_lock(&hdd_context_lock);
2622 context = &pHddCtx->ext_scan_context;
2623 ignore_cached_results = context->ignore_cached_results;
2624 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302626 if (ignore_cached_results) {
2627 hddLog(LOGE,
2628 FL("Ignore the cached results received after timeout"));
2629 return;
2630 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302631
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302632 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2633 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302634
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302635 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302636
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302637 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2638 scan_id_index++) {
2639 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302640
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302641 totalResults = result->num_results;
2642 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2643 result->scan_id, result->flags, totalResults);
2644 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302645
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302646 do{
2647 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2648 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2649 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302650
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302651 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2652 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2653
2654 if (!skb) {
2655 hddLog(VOS_TRACE_LEVEL_ERROR,
2656 FL("cfg80211_vendor_event_alloc failed"));
2657 return;
2658 }
2659
2660 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2661
2662 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2663 pData->requestId) ||
2664 nla_put_u32(skb,
2665 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2666 resultsPerEvent)) {
2667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2668 goto fail;
2669 }
2670 if (nla_put_u8(skb,
2671 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2672 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302673 {
2674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2675 goto fail;
2676 }
2677
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302678 if (nla_put_u32(skb,
2679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2680 result->scan_id)) {
2681 hddLog(LOGE, FL("put fail"));
2682 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302683 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302684
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302685 nla_results = nla_nest_start(skb,
2686 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2687 if (!nla_results)
2688 goto fail;
2689
2690 if (resultsPerEvent) {
2691 struct nlattr *aps;
2692 struct nlattr *nla_result;
2693
2694 nla_result = nla_nest_start(skb, scan_id_index);
2695 if(!nla_result)
2696 goto fail;
2697
2698 if (nla_put_u32(skb,
2699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2700 result->scan_id) ||
2701 nla_put_u32(skb,
2702 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2703 result->flags) ||
2704 nla_put_u32(skb,
2705 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2706 totalResults)) {
2707 hddLog(LOGE, FL("put fail"));
2708 goto fail;
2709 }
2710
2711 aps = nla_nest_start(skb,
2712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2713 if (!aps)
2714 {
2715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2716 goto fail;
2717 }
2718
2719 head_ptr = (tpSirWifiScanResult) &(result->ap);
2720
2721 for (j = 0; j < resultsPerEvent; j++, i++) {
2722 struct nlattr *ap;
2723 pSirWifiScanResult = head_ptr + i;
2724
2725 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05302726 * Firmware returns timestamp from extscan_start till
2727 * BSSID was cached (in micro seconds). Add this with
2728 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302729 * to derive the time since boot when the
2730 * BSSID was cached.
2731 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05302732 pSirWifiScanResult->ts +=
2733 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302734 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2735 "Ssid (%s)"
2736 "Bssid: %pM "
2737 "Channel (%u)"
2738 "Rssi (%d)"
2739 "RTT (%u)"
2740 "RTT_SD (%u)"
2741 "Beacon Period %u"
2742 "Capability 0x%x "
2743 "Ie length %d",
2744 i,
2745 pSirWifiScanResult->ts,
2746 pSirWifiScanResult->ssid,
2747 pSirWifiScanResult->bssid,
2748 pSirWifiScanResult->channel,
2749 pSirWifiScanResult->rssi,
2750 pSirWifiScanResult->rtt,
2751 pSirWifiScanResult->rtt_sd,
2752 pSirWifiScanResult->beaconPeriod,
2753 pSirWifiScanResult->capability,
2754 ieLength);
2755
2756 ap = nla_nest_start(skb, j + 1);
2757 if (!ap)
2758 {
2759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2760 goto fail;
2761 }
2762
2763 if (nla_put_u64(skb,
2764 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2765 pSirWifiScanResult->ts) )
2766 {
2767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2768 goto fail;
2769 }
2770 if (nla_put(skb,
2771 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2772 sizeof(pSirWifiScanResult->ssid),
2773 pSirWifiScanResult->ssid) )
2774 {
2775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2776 goto fail;
2777 }
2778 if (nla_put(skb,
2779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2780 sizeof(pSirWifiScanResult->bssid),
2781 pSirWifiScanResult->bssid) )
2782 {
2783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2784 goto fail;
2785 }
2786 if (nla_put_u32(skb,
2787 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2788 pSirWifiScanResult->channel) )
2789 {
2790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2791 goto fail;
2792 }
2793 if (nla_put_s32(skb,
2794 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2795 pSirWifiScanResult->rssi) )
2796 {
2797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2798 goto fail;
2799 }
2800 if (nla_put_u32(skb,
2801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2802 pSirWifiScanResult->rtt) )
2803 {
2804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2805 goto fail;
2806 }
2807 if (nla_put_u32(skb,
2808 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2809 pSirWifiScanResult->rtt_sd))
2810 {
2811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2812 goto fail;
2813 }
2814 if (nla_put_u32(skb,
2815 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2816 pSirWifiScanResult->beaconPeriod))
2817 {
2818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2819 goto fail;
2820 }
2821 if (nla_put_u32(skb,
2822 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2823 pSirWifiScanResult->capability))
2824 {
2825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2826 goto fail;
2827 }
2828 if (nla_put_u32(skb,
2829 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2830 ieLength))
2831 {
2832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2833 goto fail;
2834 }
2835
2836 if (ieLength)
2837 if (nla_put(skb,
2838 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2839 ieLength, ie)) {
2840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2841 goto fail;
2842 }
2843
2844 nla_nest_end(skb, ap);
2845 }
2846 nla_nest_end(skb, aps);
2847 nla_nest_end(skb, nla_result);
2848 }
2849
2850 nla_nest_end(skb, nla_results);
2851
2852 cfg80211_vendor_cmd_reply(skb);
2853
2854 } while (totalResults > 0);
2855 }
2856
2857 if (!pData->moreData) {
2858 spin_lock(&hdd_context_lock);
2859 context->response_status = 0;
2860 complete(&context->response_event);
2861 spin_unlock(&hdd_context_lock);
2862 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302863
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302864 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302865 return;
2866fail:
2867 kfree_skb(skb);
2868 return;
2869}
2870
2871static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2872 void *pMsg)
2873{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302874 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302875 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2876 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302877 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302878
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302879 ENTER();
2880
2881 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302882 hddLog(LOGE,
2883 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302884 return;
2885 }
2886 if (!pMsg)
2887 {
2888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302889 return;
2890 }
2891
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302892 if (pData->bss_found)
2893 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2894 else
2895 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2896
Dino Mycle6fb96c12014-06-10 11:52:40 +05302897 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302898#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2899 NULL,
2900#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302901 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302902 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302903
2904 if (!skb) {
2905 hddLog(VOS_TRACE_LEVEL_ERROR,
2906 FL("cfg80211_vendor_event_alloc failed"));
2907 return;
2908 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302909
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302910 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2911 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2912 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2913 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2914
2915 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302916 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2917 "Ssid (%s) "
2918 "Bssid (" MAC_ADDRESS_STR ") "
2919 "Channel (%u) "
2920 "Rssi (%d) "
2921 "RTT (%u) "
2922 "RTT_SD (%u) ",
2923 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302924 pData->bssHotlist[i].ts,
2925 pData->bssHotlist[i].ssid,
2926 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2927 pData->bssHotlist[i].channel,
2928 pData->bssHotlist[i].rssi,
2929 pData->bssHotlist[i].rtt,
2930 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302931 }
2932
2933 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2934 pData->requestId) ||
2935 nla_put_u32(skb,
2936 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302937 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2939 goto fail;
2940 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302941 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302942 struct nlattr *aps;
2943
2944 aps = nla_nest_start(skb,
2945 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2946 if (!aps)
2947 goto fail;
2948
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302949 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302950 struct nlattr *ap;
2951
2952 ap = nla_nest_start(skb, i + 1);
2953 if (!ap)
2954 goto fail;
2955
2956 if (nla_put_u64(skb,
2957 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302958 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302959 nla_put(skb,
2960 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302961 sizeof(pData->bssHotlist[i].ssid),
2962 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302963 nla_put(skb,
2964 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302965 sizeof(pData->bssHotlist[i].bssid),
2966 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302967 nla_put_u32(skb,
2968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302969 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302970 nla_put_s32(skb,
2971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302972 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302973 nla_put_u32(skb,
2974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302975 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302976 nla_put_u32(skb,
2977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302978 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302979 goto fail;
2980
2981 nla_nest_end(skb, ap);
2982 }
2983 nla_nest_end(skb, aps);
2984
2985 if (nla_put_u8(skb,
2986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2987 pData->moreData))
2988 goto fail;
2989 }
2990
2991 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302992 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302993 return;
2994
2995fail:
2996 kfree_skb(skb);
2997 return;
2998
2999}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303000
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303001/**
3002 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
3003 * Handle an SSID hotlist match event
3004 * @ctx: HDD context registered with SME
3005 * @event: The SSID hotlist match event
3006 *
3007 * This function will take an SSID match event that was generated by
3008 * firmware and will convert it into a cfg80211 vendor event which is
3009 * sent to userspace.
3010 *
3011 * Return: none
3012 */
3013static void
3014wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
3015 void *pMsg)
3016{
3017 hdd_context_t *hdd_ctx = ctx;
3018 struct sk_buff *skb;
3019 tANI_U32 i, index;
3020 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3021
3022 ENTER();
3023
3024 if (wlan_hdd_validate_context(hdd_ctx)) {
3025 hddLog(LOGE,
3026 FL("HDD context is not valid or response"));
3027 return;
3028 }
3029 if (!pMsg)
3030 {
3031 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3032 return;
3033 }
3034
3035 if (pData->ssid_found) {
3036 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3037 hddLog(LOG1, "SSID hotlist found");
3038 } else {
3039 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3040 hddLog(LOG1, "SSID hotlist lost");
3041 }
3042
3043 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3044#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3045 NULL,
3046#endif
3047 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3048 index, GFP_KERNEL);
3049
3050 if (!skb) {
3051 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3052 return;
3053 }
3054 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3055 pData->requestId, pData->numHotlistSsid, pData->moreData);
3056
3057 for (i = 0; i < pData->numHotlistSsid; i++) {
3058 hddLog(LOG1, "[i=%d] Timestamp %llu "
3059 "Ssid: %s "
3060 "Bssid (" MAC_ADDRESS_STR ") "
3061 "Channel %u "
3062 "Rssi %d "
3063 "RTT %u "
3064 "RTT_SD %u",
3065 i,
3066 pData->ssidHotlist[i].ts,
3067 pData->ssidHotlist[i].ssid,
3068 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3069 pData->ssidHotlist[i].channel,
3070 pData->ssidHotlist[i].rssi,
3071 pData->ssidHotlist[i].rtt,
3072 pData->ssidHotlist[i].rtt_sd);
3073 }
3074
3075 if (nla_put_u32(skb,
3076 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3077 pData->requestId) ||
3078 nla_put_u32(skb,
3079 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3080 pData->numHotlistSsid)) {
3081 hddLog(LOGE, FL("put fail"));
3082 goto fail;
3083 }
3084
3085 if (pData->numHotlistSsid) {
3086 struct nlattr *aps;
3087 aps = nla_nest_start(skb,
3088 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3089 if (!aps) {
3090 hddLog(LOGE, FL("nest fail"));
3091 goto fail;
3092 }
3093
3094 for (i = 0; i < pData->numHotlistSsid; i++) {
3095 struct nlattr *ap;
3096
3097 ap = nla_nest_start(skb, i);
3098 if (!ap) {
3099 hddLog(LOGE, FL("nest fail"));
3100 goto fail;
3101 }
3102
3103 if (nla_put_u64(skb,
3104 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3105 pData->ssidHotlist[i].ts) ||
3106 nla_put(skb,
3107 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3108 sizeof(pData->ssidHotlist[i].ssid),
3109 pData->ssidHotlist[i].ssid) ||
3110 nla_put(skb,
3111 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3112 sizeof(pData->ssidHotlist[i].bssid),
3113 pData->ssidHotlist[i].bssid) ||
3114 nla_put_u32(skb,
3115 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3116 pData->ssidHotlist[i].channel) ||
3117 nla_put_s32(skb,
3118 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3119 pData->ssidHotlist[i].rssi) ||
3120 nla_put_u32(skb,
3121 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3122 pData->ssidHotlist[i].rtt) ||
3123 nla_put_u32(skb,
3124 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3125 pData->ssidHotlist[i].rtt_sd)) {
3126 hddLog(LOGE, FL("put fail"));
3127 goto fail;
3128 }
3129 nla_nest_end(skb, ap);
3130 }
3131 nla_nest_end(skb, aps);
3132
3133 if (nla_put_u8(skb,
3134 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3135 pData->moreData)) {
3136 hddLog(LOGE, FL("put fail"));
3137 goto fail;
3138 }
3139 }
3140
3141 cfg80211_vendor_event(skb, GFP_KERNEL);
3142 return;
3143
3144fail:
3145 kfree_skb(skb);
3146 return;
3147
3148}
3149
3150
Dino Mycle6fb96c12014-06-10 11:52:40 +05303151static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3152 void *pMsg)
3153{
3154 struct sk_buff *skb;
3155 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3156 tpSirWifiFullScanResultEvent pData =
3157 (tpSirWifiFullScanResultEvent) (pMsg);
3158
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303159 ENTER();
3160
3161 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303162 hddLog(LOGE,
3163 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303164 return;
3165 }
3166 if (!pMsg)
3167 {
3168 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303169 return;
3170 }
3171
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303172 /*
3173 * If the full scan result including IE data exceeds NL 4K size
3174 * limitation, drop that beacon/probe rsp frame.
3175 */
3176 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3177 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3178 return;
3179 }
3180
Dino Mycle6fb96c12014-06-10 11:52:40 +05303181 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303182#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3183 NULL,
3184#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303185 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3186 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3187 GFP_KERNEL);
3188
3189 if (!skb) {
3190 hddLog(VOS_TRACE_LEVEL_ERROR,
3191 FL("cfg80211_vendor_event_alloc failed"));
3192 return;
3193 }
3194
Dino Mycle6fb96c12014-06-10 11:52:40 +05303195 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3196 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3197 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3198 "Ssid (%s)"
3199 "Bssid (" MAC_ADDRESS_STR ")"
3200 "Channel (%u)"
3201 "Rssi (%d)"
3202 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303203 "RTT_SD (%u)"
3204 "Bcn Period %d"
3205 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303206 pData->ap.ts,
3207 pData->ap.ssid,
3208 MAC_ADDR_ARRAY(pData->ap.bssid),
3209 pData->ap.channel,
3210 pData->ap.rssi,
3211 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303212 pData->ap.rtt_sd,
3213 pData->ap.beaconPeriod,
3214 pData->ap.capability);
3215
Dino Mycle6fb96c12014-06-10 11:52:40 +05303216 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3217 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3218 pData->requestId) ||
3219 nla_put_u64(skb,
3220 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3221 pData->ap.ts) ||
3222 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3223 sizeof(pData->ap.ssid),
3224 pData->ap.ssid) ||
3225 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3226 WNI_CFG_BSSID_LEN,
3227 pData->ap.bssid) ||
3228 nla_put_u32(skb,
3229 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3230 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303231 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303232 pData->ap.rssi) ||
3233 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3234 pData->ap.rtt) ||
3235 nla_put_u32(skb,
3236 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3237 pData->ap.rtt_sd) ||
3238 nla_put_u16(skb,
3239 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3240 pData->ap.beaconPeriod) ||
3241 nla_put_u16(skb,
3242 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3243 pData->ap.capability) ||
3244 nla_put_u32(skb,
3245 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303246 pData->ieLength) ||
3247 nla_put_u8(skb,
3248 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3249 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303250 {
3251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3252 goto nla_put_failure;
3253 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303254
3255 if (pData->ieLength) {
3256 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3257 pData->ieLength,
3258 pData->ie))
3259 {
3260 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3261 goto nla_put_failure;
3262 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303263 }
3264
3265 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303266 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303267 return;
3268
3269nla_put_failure:
3270 kfree_skb(skb);
3271 return;
3272}
3273
3274static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3275 void *pMsg)
3276{
3277 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3278 struct sk_buff *skb = NULL;
3279 tpSirEXTScanResultsAvailableIndParams pData =
3280 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3281
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303282 ENTER();
3283
3284 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303285 hddLog(LOGE,
3286 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303287 return;
3288 }
3289 if (!pMsg)
3290 {
3291 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303292 return;
3293 }
3294
3295 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303296#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3297 NULL,
3298#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303299 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3300 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3301 GFP_KERNEL);
3302
3303 if (!skb) {
3304 hddLog(VOS_TRACE_LEVEL_ERROR,
3305 FL("cfg80211_vendor_event_alloc failed"));
3306 return;
3307 }
3308
Dino Mycle6fb96c12014-06-10 11:52:40 +05303309 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3310 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3311 pData->numResultsAvailable);
3312 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3313 pData->requestId) ||
3314 nla_put_u32(skb,
3315 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3316 pData->numResultsAvailable)) {
3317 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3318 goto nla_put_failure;
3319 }
3320
3321 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303322 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303323 return;
3324
3325nla_put_failure:
3326 kfree_skb(skb);
3327 return;
3328}
3329
3330static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3331{
3332 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3333 struct sk_buff *skb = NULL;
3334 tpSirEXTScanProgressIndParams pData =
3335 (tpSirEXTScanProgressIndParams) pMsg;
3336
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303337 ENTER();
3338
3339 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303340 hddLog(LOGE,
3341 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303342 return;
3343 }
3344 if (!pMsg)
3345 {
3346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303347 return;
3348 }
3349
3350 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303351#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3352 NULL,
3353#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303354 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3355 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3356 GFP_KERNEL);
3357
3358 if (!skb) {
3359 hddLog(VOS_TRACE_LEVEL_ERROR,
3360 FL("cfg80211_vendor_event_alloc failed"));
3361 return;
3362 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303363 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303364 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3365 pData->extScanEventType);
3366 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3367 pData->status);
3368
3369 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3370 pData->extScanEventType) ||
3371 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303372 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3373 pData->requestId) ||
3374 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303375 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3376 pData->status)) {
3377 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3378 goto nla_put_failure;
3379 }
3380
3381 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303382 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303383 return;
3384
3385nla_put_failure:
3386 kfree_skb(skb);
3387 return;
3388}
3389
3390void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3391 void *pMsg)
3392{
3393 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3394
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303395 ENTER();
3396
Dino Mycle6fb96c12014-06-10 11:52:40 +05303397 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303398 return;
3399 }
3400
3401 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3402
3403
3404 switch(evType) {
3405 case SIR_HAL_EXTSCAN_START_RSP:
3406 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3407 break;
3408
3409 case SIR_HAL_EXTSCAN_STOP_RSP:
3410 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3411 break;
3412 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3413 /* There is no need to send this response to upper layer
3414 Just log the message */
3415 hddLog(VOS_TRACE_LEVEL_INFO,
3416 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3417 break;
3418 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3419 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3420 break;
3421
3422 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3423 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3424 break;
3425
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303426 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3427 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3428 break;
3429
3430 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3431 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3432 break;
3433
Dino Mycle6fb96c12014-06-10 11:52:40 +05303434 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303435 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303436 break;
3437 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3438 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3439 break;
3440 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3441 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3442 break;
3443 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3444 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3445 break;
3446 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3447 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3448 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303449 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3450 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3451 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303452 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3453 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3454 break;
3455 default:
3456 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3457 break;
3458 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303459 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460}
3461
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303462static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3463 struct wireless_dev *wdev,
3464 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303465{
Dino Myclee8843b32014-07-04 14:21:45 +05303466 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303467 struct net_device *dev = wdev->netdev;
3468 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3469 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3470 struct nlattr
3471 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3472 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303473 struct hdd_ext_scan_context *context;
3474 unsigned long rc;
3475 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303476
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303477 ENTER();
3478
Dino Mycle6fb96c12014-06-10 11:52:40 +05303479 status = wlan_hdd_validate_context(pHddCtx);
3480 if (0 != status)
3481 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303482 return -EINVAL;
3483 }
Dino Myclee8843b32014-07-04 14:21:45 +05303484 /* check the EXTScan Capability */
3485 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303486 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3487 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303488 {
3489 hddLog(VOS_TRACE_LEVEL_ERROR,
3490 FL("EXTScan not enabled/supported by Firmware"));
3491 return -EINVAL;
3492 }
3493
Dino Mycle6fb96c12014-06-10 11:52:40 +05303494 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3495 data, dataLen,
3496 wlan_hdd_extscan_config_policy)) {
3497 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3498 return -EINVAL;
3499 }
3500
3501 /* Parse and fetch request Id */
3502 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3503 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3504 return -EINVAL;
3505 }
3506
Dino Myclee8843b32014-07-04 14:21:45 +05303507 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303508 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303509 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303510
Dino Myclee8843b32014-07-04 14:21:45 +05303511 reqMsg.sessionId = pAdapter->sessionId;
3512 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303513
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303514 vos_spin_lock_acquire(&hdd_context_lock);
3515 context = &pHddCtx->ext_scan_context;
3516 context->request_id = reqMsg.requestId;
3517 INIT_COMPLETION(context->response_event);
3518 vos_spin_lock_release(&hdd_context_lock);
3519
Dino Myclee8843b32014-07-04 14:21:45 +05303520 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303521 if (!HAL_STATUS_SUCCESS(status)) {
3522 hddLog(VOS_TRACE_LEVEL_ERROR,
3523 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303524 return -EINVAL;
3525 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303526
3527 rc = wait_for_completion_timeout(&context->response_event,
3528 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3529 if (!rc) {
3530 hddLog(LOGE, FL("Target response timed out"));
3531 return -ETIMEDOUT;
3532 }
3533
3534 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3535 if (ret)
3536 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3537
3538 return ret;
3539
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303540 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303541 return 0;
3542}
3543
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303544static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3545 struct wireless_dev *wdev,
3546 const void *data, int dataLen)
3547{
3548 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303549
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303550 vos_ssr_protect(__func__);
3551 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3552 vos_ssr_unprotect(__func__);
3553
3554 return ret;
3555}
3556
3557static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3558 struct wireless_dev *wdev,
3559 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303560{
Dino Myclee8843b32014-07-04 14:21:45 +05303561 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303562 struct net_device *dev = wdev->netdev;
3563 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3564 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3565 struct nlattr
3566 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3567 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303568 struct hdd_ext_scan_context *context;
3569 unsigned long rc;
3570 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303571
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303572 ENTER();
3573
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303574 if (VOS_FTM_MODE == hdd_get_conparam()) {
3575 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3576 return -EINVAL;
3577 }
3578
Dino Mycle6fb96c12014-06-10 11:52:40 +05303579 status = wlan_hdd_validate_context(pHddCtx);
3580 if (0 != status)
3581 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303582 return -EINVAL;
3583 }
Dino Myclee8843b32014-07-04 14:21:45 +05303584 /* check the EXTScan Capability */
3585 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303586 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3587 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303588 {
3589 hddLog(VOS_TRACE_LEVEL_ERROR,
3590 FL("EXTScan not enabled/supported by Firmware"));
3591 return -EINVAL;
3592 }
3593
Dino Mycle6fb96c12014-06-10 11:52:40 +05303594 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3595 data, dataLen,
3596 wlan_hdd_extscan_config_policy)) {
3597 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3598 return -EINVAL;
3599 }
3600 /* Parse and fetch request Id */
3601 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3602 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3603 return -EINVAL;
3604 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303605
Dino Myclee8843b32014-07-04 14:21:45 +05303606 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303607 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3608
Dino Myclee8843b32014-07-04 14:21:45 +05303609 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303610
Dino Myclee8843b32014-07-04 14:21:45 +05303611 reqMsg.sessionId = pAdapter->sessionId;
3612 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303613
3614 /* Parse and fetch flush parameter */
3615 if (!tb
3616 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3617 {
3618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3619 goto failed;
3620 }
Dino Myclee8843b32014-07-04 14:21:45 +05303621 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303622 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3623
Dino Myclee8843b32014-07-04 14:21:45 +05303624 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303626 spin_lock(&hdd_context_lock);
3627 context = &pHddCtx->ext_scan_context;
3628 context->request_id = reqMsg.requestId;
3629 context->ignore_cached_results = false;
3630 INIT_COMPLETION(context->response_event);
3631 spin_unlock(&hdd_context_lock);
3632
Dino Myclee8843b32014-07-04 14:21:45 +05303633 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303634 if (!HAL_STATUS_SUCCESS(status)) {
3635 hddLog(VOS_TRACE_LEVEL_ERROR,
3636 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303637 return -EINVAL;
3638 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303639
3640 rc = wait_for_completion_timeout(&context->response_event,
3641 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3642 if (!rc) {
3643 hddLog(LOGE, FL("Target response timed out"));
3644 retval = -ETIMEDOUT;
3645 spin_lock(&hdd_context_lock);
3646 context->ignore_cached_results = true;
3647 spin_unlock(&hdd_context_lock);
3648 } else {
3649 spin_lock(&hdd_context_lock);
3650 retval = context->response_status;
3651 spin_unlock(&hdd_context_lock);
3652 }
3653
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303654 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303655 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303656
3657failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303658 return -EINVAL;
3659}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303660static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3661 struct wireless_dev *wdev,
3662 const void *data, int dataLen)
3663{
3664 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303665
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303666 vos_ssr_protect(__func__);
3667 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3668 vos_ssr_unprotect(__func__);
3669
3670 return ret;
3671}
3672
3673static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303674 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303675 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303676{
3677 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3678 struct net_device *dev = wdev->netdev;
3679 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3680 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3681 struct nlattr
3682 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3683 struct nlattr
3684 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3685 struct nlattr *apTh;
3686 eHalStatus status;
3687 tANI_U8 i = 0;
3688 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303689 struct hdd_ext_scan_context *context;
3690 tANI_U32 request_id;
3691 unsigned long rc;
3692 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303693
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303694 ENTER();
3695
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303696 if (VOS_FTM_MODE == hdd_get_conparam()) {
3697 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3698 return -EINVAL;
3699 }
3700
Dino Mycle6fb96c12014-06-10 11:52:40 +05303701 status = wlan_hdd_validate_context(pHddCtx);
3702 if (0 != status)
3703 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303704 return -EINVAL;
3705 }
Dino Myclee8843b32014-07-04 14:21:45 +05303706 /* check the EXTScan Capability */
3707 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303708 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3709 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303710 {
3711 hddLog(VOS_TRACE_LEVEL_ERROR,
3712 FL("EXTScan not enabled/supported by Firmware"));
3713 return -EINVAL;
3714 }
3715
Dino Mycle6fb96c12014-06-10 11:52:40 +05303716 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3717 data, dataLen,
3718 wlan_hdd_extscan_config_policy)) {
3719 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3720 return -EINVAL;
3721 }
3722
3723 /* Parse and fetch request Id */
3724 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3726 return -EINVAL;
3727 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303728 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3729 vos_mem_malloc(sizeof(*pReqMsg));
3730 if (!pReqMsg) {
3731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3732 return -ENOMEM;
3733 }
3734
Dino Myclee8843b32014-07-04 14:21:45 +05303735
Dino Mycle6fb96c12014-06-10 11:52:40 +05303736 pReqMsg->requestId = nla_get_u32(
3737 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3738 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3739
3740 /* Parse and fetch number of APs */
3741 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3742 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3743 goto fail;
3744 }
3745
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303746 /* Parse and fetch lost ap sample size */
3747 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3748 hddLog(LOGE, FL("attr lost ap sample size failed"));
3749 goto fail;
3750 }
3751
3752 pReqMsg->lostBssidSampleSize = nla_get_u32(
3753 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3754 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3755
Dino Mycle6fb96c12014-06-10 11:52:40 +05303756 pReqMsg->sessionId = pAdapter->sessionId;
3757 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3758
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303759 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303760 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303761 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303762
3763 nla_for_each_nested(apTh,
3764 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3765 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3766 nla_data(apTh), nla_len(apTh),
3767 NULL)) {
3768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3769 goto fail;
3770 }
3771
3772 /* Parse and fetch MAC address */
3773 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3775 goto fail;
3776 }
3777 memcpy(pReqMsg->ap[i].bssid, nla_data(
3778 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3779 sizeof(tSirMacAddr));
3780 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3781
3782 /* Parse and fetch low RSSI */
3783 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3785 goto fail;
3786 }
3787 pReqMsg->ap[i].low = nla_get_s32(
3788 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3789 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3790
3791 /* Parse and fetch high RSSI */
3792 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3794 goto fail;
3795 }
3796 pReqMsg->ap[i].high = nla_get_s32(
3797 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3798 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3799 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303800 i++;
3801 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303802
3803 context = &pHddCtx->ext_scan_context;
3804 spin_lock(&hdd_context_lock);
3805 INIT_COMPLETION(context->response_event);
3806 context->request_id = request_id = pReqMsg->requestId;
3807 spin_unlock(&hdd_context_lock);
3808
Dino Mycle6fb96c12014-06-10 11:52:40 +05303809 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3810 if (!HAL_STATUS_SUCCESS(status)) {
3811 hddLog(VOS_TRACE_LEVEL_ERROR,
3812 FL("sme_SetBssHotlist failed(err=%d)"), status);
3813 vos_mem_free(pReqMsg);
3814 return -EINVAL;
3815 }
3816
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303817 /* request was sent -- wait for the response */
3818 rc = wait_for_completion_timeout(&context->response_event,
3819 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3820
3821 if (!rc) {
3822 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3823 retval = -ETIMEDOUT;
3824 } else {
3825 spin_lock(&hdd_context_lock);
3826 if (context->request_id == request_id)
3827 retval = context->response_status;
3828 else
3829 retval = -EINVAL;
3830 spin_unlock(&hdd_context_lock);
3831 }
3832
Dino Myclee8843b32014-07-04 14:21:45 +05303833 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303834 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303835 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303836
3837fail:
3838 vos_mem_free(pReqMsg);
3839 return -EINVAL;
3840}
3841
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303842static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3843 struct wireless_dev *wdev,
3844 const void *data, int dataLen)
3845{
3846 int ret = 0;
3847
3848 vos_ssr_protect(__func__);
3849 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3850 dataLen);
3851 vos_ssr_unprotect(__func__);
3852
3853 return ret;
3854}
3855
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303856/*
3857 * define short names for the global vendor params
3858 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3859 */
3860#define PARAM_MAX \
3861QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3862#define PARAM_REQUEST_ID \
3863QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3864#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3865QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3866#define PARAMS_NUM_SSID \
3867QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3868#define THRESHOLD_PARAM \
3869QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3870#define PARAM_SSID \
3871QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3872#define PARAM_BAND \
3873QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3874#define PARAM_RSSI_LOW \
3875QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3876#define PARAM_RSSI_HIGH \
3877QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3878
3879/**
3880 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3881 * @wiphy: Pointer to wireless phy
3882 * @wdev: Pointer to wireless device
3883 * @data: Pointer to data
3884 * @data_len: Data length
3885 *
3886 * Return: 0 on success, negative errno on failure
3887 */
3888static int
3889__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3890 struct wireless_dev *wdev,
3891 const void *data,
3892 int data_len)
3893{
3894 tSirEXTScanSetSsidHotListReqParams *request;
3895 struct net_device *dev = wdev->netdev;
3896 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3897 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3898 struct nlattr *tb[PARAM_MAX + 1];
3899 struct nlattr *tb2[PARAM_MAX + 1];
3900 struct nlattr *ssids;
3901 struct hdd_ext_scan_context *context;
3902 uint32_t request_id;
3903 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3904 int ssid_len;
Anurag Chouhand64d5232016-08-29 17:01:38 +05303905 int ssid_length;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303906 eHalStatus status;
3907 int i, rem, retval;
3908 unsigned long rc;
3909
3910 ENTER();
3911
3912 if (VOS_FTM_MODE == hdd_get_conparam()) {
3913 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3914 return -EINVAL;
3915 }
3916
3917 retval = wlan_hdd_validate_context(hdd_ctx);
3918 if (0 != retval) {
3919 hddLog(LOGE, FL("HDD context is not valid"));
3920 return -EINVAL;
3921 }
3922
3923 /* check the EXTScan Capability */
3924 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303925 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3926 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303927 {
3928 hddLog(VOS_TRACE_LEVEL_ERROR,
3929 FL("EXTScan not enabled/supported by Firmware"));
3930 return -EINVAL;
3931 }
3932
3933 if (nla_parse(tb, PARAM_MAX,
3934 data, data_len,
3935 wlan_hdd_extscan_config_policy)) {
3936 hddLog(LOGE, FL("Invalid ATTR"));
3937 return -EINVAL;
3938 }
3939
3940 request = vos_mem_malloc(sizeof(*request));
3941 if (!request) {
3942 hddLog(LOGE, FL("vos_mem_malloc failed"));
3943 return -ENOMEM;
3944 }
3945
3946 /* Parse and fetch request Id */
3947 if (!tb[PARAM_REQUEST_ID]) {
3948 hddLog(LOGE, FL("attr request id failed"));
3949 goto fail;
3950 }
3951
3952 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3953 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3954
3955 /* Parse and fetch lost SSID sample size */
3956 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3957 hddLog(LOGE, FL("attr number of Ssid failed"));
3958 goto fail;
3959 }
3960 request->lost_ssid_sample_size =
3961 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3962 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3963 request->lost_ssid_sample_size);
3964
3965 /* Parse and fetch number of hotlist SSID */
3966 if (!tb[PARAMS_NUM_SSID]) {
3967 hddLog(LOGE, FL("attr number of Ssid failed"));
3968 goto fail;
3969 }
3970 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3971 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3972
3973 request->session_id = adapter->sessionId;
3974 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3975
3976 i = 0;
3977 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3978 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3979 hddLog(LOGE,
3980 FL("Too Many SSIDs, %d exceeds %d"),
3981 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3982 break;
3983 }
3984 if (nla_parse(tb2, PARAM_MAX,
3985 nla_data(ssids), nla_len(ssids),
3986 wlan_hdd_extscan_config_policy)) {
3987 hddLog(LOGE, FL("nla_parse failed"));
3988 goto fail;
3989 }
3990
3991 /* Parse and fetch SSID */
3992 if (!tb2[PARAM_SSID]) {
3993 hddLog(LOGE, FL("attr ssid failed"));
3994 goto fail;
3995 }
Anurag Chouhand64d5232016-08-29 17:01:38 +05303996 ssid_length = nla_strlcpy(ssid_string, tb2[PARAM_SSID],
3997 sizeof(ssid_string));
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303998 hddLog(LOG1, FL("SSID %s"),
3999 ssid_string);
4000 ssid_len = strlen(ssid_string);
Anurag Chouhand64d5232016-08-29 17:01:38 +05304001 if (ssid_length > SIR_MAC_MAX_SSID_LENGTH) {
4002 hddLog(LOGE, FL("Invalid ssid length"));
4003 goto fail;
4004 }
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304005 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
4006 request->ssid[i].ssid.length = ssid_len;
4007 request->ssid[i].ssid.ssId[ssid_len] = '\0';
4008 hddLog(LOG1, FL("After copying SSID %s"),
4009 request->ssid[i].ssid.ssId);
4010 hddLog(LOG1, FL("After copying length: %d"),
4011 ssid_len);
4012
4013 /* Parse and fetch low RSSI */
4014 if (!tb2[PARAM_BAND]) {
4015 hddLog(LOGE, FL("attr band failed"));
4016 goto fail;
4017 }
4018 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
4019 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
4020
4021 /* Parse and fetch low RSSI */
4022 if (!tb2[PARAM_RSSI_LOW]) {
4023 hddLog(LOGE, FL("attr low RSSI failed"));
4024 goto fail;
4025 }
4026 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4027 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4028
4029 /* Parse and fetch high RSSI */
4030 if (!tb2[PARAM_RSSI_HIGH]) {
4031 hddLog(LOGE, FL("attr high RSSI failed"));
4032 goto fail;
4033 }
4034 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4035 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4036 i++;
4037 }
4038
4039 context = &hdd_ctx->ext_scan_context;
4040 spin_lock(&hdd_context_lock);
4041 INIT_COMPLETION(context->response_event);
4042 context->request_id = request_id = request->request_id;
4043 spin_unlock(&hdd_context_lock);
4044
4045 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4046 if (!HAL_STATUS_SUCCESS(status)) {
4047 hddLog(LOGE,
4048 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4049 goto fail;
4050 }
4051
4052 vos_mem_free(request);
4053
4054 /* request was sent -- wait for the response */
4055 rc = wait_for_completion_timeout(&context->response_event,
4056 msecs_to_jiffies
4057 (WLAN_WAIT_TIME_EXTSCAN));
4058 if (!rc) {
4059 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4060 retval = -ETIMEDOUT;
4061 } else {
4062 spin_lock(&hdd_context_lock);
4063 if (context->request_id == request_id)
4064 retval = context->response_status;
4065 else
4066 retval = -EINVAL;
4067 spin_unlock(&hdd_context_lock);
4068 }
4069
4070 return retval;
4071
4072fail:
4073 vos_mem_free(request);
4074 return -EINVAL;
4075}
4076
4077/*
4078 * done with short names for the global vendor params
4079 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4080 */
4081#undef PARAM_MAX
4082#undef PARAM_REQUEST_ID
4083#undef PARAMS_NUM_SSID
4084#undef THRESHOLD_PARAM
4085#undef PARAM_SSID
4086#undef PARAM_BAND
4087#undef PARAM_RSSI_LOW
4088#undef PARAM_RSSI_HIGH
4089
4090static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4091 struct wireless_dev *wdev,
4092 const void *data, int dataLen)
4093{
4094 int ret = 0;
4095
4096 vos_ssr_protect(__func__);
4097 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4098 dataLen);
4099 vos_ssr_unprotect(__func__);
4100
4101 return ret;
4102}
4103
4104static int
4105__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4106 struct wireless_dev *wdev,
4107 const void *data,
4108 int data_len)
4109{
4110 tSirEXTScanResetSsidHotlistReqParams request;
4111 struct net_device *dev = wdev->netdev;
4112 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4113 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4114 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4115 struct hdd_ext_scan_context *context;
4116 uint32_t request_id;
4117 eHalStatus status;
4118 int retval;
4119 unsigned long rc;
4120
4121 ENTER();
4122
4123 if (VOS_FTM_MODE == hdd_get_conparam()) {
4124 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4125 return -EINVAL;
4126 }
4127
4128 retval = wlan_hdd_validate_context(hdd_ctx);
4129 if (0 != retval) {
4130 hddLog(LOGE, FL("HDD context is not valid"));
4131 return -EINVAL;
4132 }
4133
4134 /* check the EXTScan Capability */
4135 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304136 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4137 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304138 {
4139 hddLog(LOGE,
4140 FL("EXTScan not enabled/supported by Firmware"));
4141 return -EINVAL;
4142 }
4143
4144 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4145 data, data_len,
4146 wlan_hdd_extscan_config_policy)) {
4147 hddLog(LOGE, FL("Invalid ATTR"));
4148 return -EINVAL;
4149 }
4150
4151 /* Parse and fetch request Id */
4152 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4153 hddLog(LOGE, FL("attr request id failed"));
4154 return -EINVAL;
4155 }
4156
4157 request.requestId = nla_get_u32(
4158 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4159 request.sessionId = adapter->sessionId;
4160 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4161 request.sessionId);
4162
4163 context = &hdd_ctx->ext_scan_context;
4164 spin_lock(&hdd_context_lock);
4165 INIT_COMPLETION(context->response_event);
4166 context->request_id = request_id = request.requestId;
4167 spin_unlock(&hdd_context_lock);
4168
4169 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4170 if (!HAL_STATUS_SUCCESS(status)) {
4171 hddLog(LOGE,
4172 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4173 return -EINVAL;
4174 }
4175
4176 /* request was sent -- wait for the response */
4177 rc = wait_for_completion_timeout(&context->response_event,
4178 msecs_to_jiffies
4179 (WLAN_WAIT_TIME_EXTSCAN));
4180 if (!rc) {
4181 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4182 retval = -ETIMEDOUT;
4183 } else {
4184 spin_lock(&hdd_context_lock);
4185 if (context->request_id == request_id)
4186 retval = context->response_status;
4187 else
4188 retval = -EINVAL;
4189 spin_unlock(&hdd_context_lock);
4190 }
4191
4192 return retval;
4193}
4194
4195static int
4196wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4197 struct wireless_dev *wdev,
4198 const void *data,
4199 int data_len)
4200{
4201 int ret;
4202
4203 vos_ssr_protect(__func__);
4204 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4205 data, data_len);
4206 vos_ssr_unprotect(__func__);
4207
4208 return ret;
4209}
4210
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304211static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304212 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304213 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304214{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304215 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4216 struct net_device *dev = wdev->netdev;
4217 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4218 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4219 uint8_t num_channels = 0;
4220 uint8_t num_chan_new = 0;
4221 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304222 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304223 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304224 tWifiBand wifiBand;
4225 eHalStatus status;
4226 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304227 tANI_U8 i,j,k;
4228 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304229
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304230 ENTER();
4231
Dino Mycle6fb96c12014-06-10 11:52:40 +05304232 status = wlan_hdd_validate_context(pHddCtx);
4233 if (0 != status)
4234 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304235 return -EINVAL;
4236 }
Dino Myclee8843b32014-07-04 14:21:45 +05304237
Dino Mycle6fb96c12014-06-10 11:52:40 +05304238 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4239 data, dataLen,
4240 wlan_hdd_extscan_config_policy)) {
4241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4242 return -EINVAL;
4243 }
4244
4245 /* Parse and fetch request Id */
4246 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4247 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4248 return -EINVAL;
4249 }
4250 requestId = nla_get_u32(
4251 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4252 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4253
4254 /* Parse and fetch wifi band */
4255 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4256 {
4257 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4258 return -EINVAL;
4259 }
4260 wifiBand = nla_get_u32(
4261 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4262 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4263
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304264 /* Parse and fetch max channels */
4265 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4266 {
4267 hddLog(LOGE, FL("attr max channels failed"));
4268 return -EINVAL;
4269 }
4270 maxChannels = nla_get_u32(
4271 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4272 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4273
Dino Mycle6fb96c12014-06-10 11:52:40 +05304274 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304275 wifiBand, chan_list,
4276 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304277 if (eHAL_STATUS_SUCCESS != status) {
4278 hddLog(VOS_TRACE_LEVEL_ERROR,
4279 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4280 return -EINVAL;
4281 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304282
Agrawal Ashish16abf782016-08-18 22:42:59 +05304283 num_channels = VOS_MIN(num_channels, maxChannels);
4284 num_chan_new = num_channels;
4285 /* remove the indoor only channels if iface is SAP */
4286 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4287 {
4288 num_chan_new = 0;
4289 for (i = 0; i < num_channels; i++)
4290 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
4291 if (wiphy->bands[j] == NULL)
4292 continue;
4293 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4294 if ((chan_list[i] ==
4295 wiphy->bands[j]->channels[k].center_freq) &&
4296 (!(wiphy->bands[j]->channels[k].flags &
4297 IEEE80211_CHAN_INDOOR_ONLY))) {
4298 chan_list[num_chan_new] = chan_list[i];
4299 num_chan_new++;
4300 }
4301 }
4302 }
4303 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304304
Agrawal Ashish16abf782016-08-18 22:42:59 +05304305 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4306 for (i = 0; i < num_chan_new; i++)
4307 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4308 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304309
4310 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304311 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304312 NLMSG_HDRLEN);
4313
4314 if (!replySkb) {
4315 hddLog(VOS_TRACE_LEVEL_ERROR,
4316 FL("valid channels: buffer alloc fail"));
4317 return -EINVAL;
4318 }
4319 if (nla_put_u32(replySkb,
4320 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304321 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304322 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304323 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304324
4325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4326 kfree_skb(replySkb);
4327 return -EINVAL;
4328 }
4329
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304330 ret = cfg80211_vendor_cmd_reply(replySkb);
4331
4332 EXIT();
4333 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304334}
4335
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304336static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4337 struct wireless_dev *wdev,
4338 const void *data, int dataLen)
4339{
4340 int ret = 0;
4341
4342 vos_ssr_protect(__func__);
4343 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4344 dataLen);
4345 vos_ssr_unprotect(__func__);
4346
4347 return ret;
4348}
4349
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304350static int hdd_extscan_start_fill_bucket_channel_spec(
4351 hdd_context_t *pHddCtx,
4352 tpSirEXTScanStartReqParams pReqMsg,
4353 struct nlattr **tb)
4354{
4355 struct nlattr *bucket[
4356 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4357 struct nlattr *channel[
4358 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4359 struct nlattr *buckets;
4360 struct nlattr *channels;
4361 int rem1, rem2;
4362 eHalStatus status;
4363 tANI_U8 bktIndex, j, numChannels;
4364 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4365 tANI_U32 passive_max_chn_time, active_max_chn_time;
4366
4367 bktIndex = 0;
4368
4369 nla_for_each_nested(buckets,
4370 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4371 if (nla_parse(bucket,
4372 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4373 nla_data(buckets), nla_len(buckets), NULL)) {
4374 hddLog(LOGE, FL("nla_parse failed"));
4375 return -EINVAL;
4376 }
4377
4378 /* Parse and fetch bucket spec */
4379 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4380 hddLog(LOGE, FL("attr bucket index failed"));
4381 return -EINVAL;
4382 }
4383 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4384 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4385 hddLog(LOG1, FL("Bucket spec Index %d"),
4386 pReqMsg->buckets[bktIndex].bucket);
4387
4388 /* Parse and fetch wifi band */
4389 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4390 hddLog(LOGE, FL("attr wifi band failed"));
4391 return -EINVAL;
4392 }
4393 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4394 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4395 hddLog(LOG1, FL("Wifi band %d"),
4396 pReqMsg->buckets[bktIndex].band);
4397
4398 /* Parse and fetch period */
4399 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4400 hddLog(LOGE, FL("attr period failed"));
4401 return -EINVAL;
4402 }
4403 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4404 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4405 hddLog(LOG1, FL("period %d"),
4406 pReqMsg->buckets[bktIndex].period);
4407
4408 /* Parse and fetch report events */
4409 if (!bucket[
4410 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4411 hddLog(LOGE, FL("attr report events failed"));
4412 return -EINVAL;
4413 }
4414 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4415 bucket[
4416 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4417 hddLog(LOG1, FL("report events %d"),
4418 pReqMsg->buckets[bktIndex].reportEvents);
4419
4420 /* Parse and fetch max period */
4421 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4422 hddLog(LOGE, FL("attr max period failed"));
4423 return -EINVAL;
4424 }
4425 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4426 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4427 hddLog(LOG1, FL("max period %u"),
4428 pReqMsg->buckets[bktIndex].max_period);
4429
4430 /* Parse and fetch exponent */
4431 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4432 hddLog(LOGE, FL("attr exponent failed"));
4433 return -EINVAL;
4434 }
4435 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4436 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4437 hddLog(LOG1, FL("exponent %u"),
4438 pReqMsg->buckets[bktIndex].exponent);
4439
4440 /* Parse and fetch step count */
4441 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4442 hddLog(LOGE, FL("attr step count failed"));
4443 return -EINVAL;
4444 }
4445 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4446 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4447 hddLog(LOG1, FL("Step count %u"),
4448 pReqMsg->buckets[bktIndex].step_count);
4449
4450 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4451 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4452
4453 /* Framework shall pass the channel list if the input WiFi band is
4454 * WIFI_BAND_UNSPECIFIED.
4455 * If the input WiFi band is specified (any value other than
4456 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4457 */
4458 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4459 numChannels = 0;
4460 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4461 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4462 pReqMsg->buckets[bktIndex].band,
4463 chanList, &numChannels);
4464 if (!HAL_STATUS_SUCCESS(status)) {
4465 hddLog(LOGE,
4466 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4467 status);
4468 return -EINVAL;
4469 }
4470
4471 pReqMsg->buckets[bktIndex].numChannels =
4472 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4473 hddLog(LOG1, FL("Num channels %d"),
4474 pReqMsg->buckets[bktIndex].numChannels);
4475
4476 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4477 j++) {
4478 pReqMsg->buckets[bktIndex].channels[j].channel =
4479 chanList[j];
4480 pReqMsg->buckets[bktIndex].channels[j].
4481 chnlClass = 0;
4482 if (CSR_IS_CHANNEL_DFS(
4483 vos_freq_to_chan(chanList[j]))) {
4484 pReqMsg->buckets[bktIndex].channels[j].
4485 passive = 1;
4486 pReqMsg->buckets[bktIndex].channels[j].
4487 dwellTimeMs = passive_max_chn_time;
4488 } else {
4489 pReqMsg->buckets[bktIndex].channels[j].
4490 passive = 0;
4491 pReqMsg->buckets[bktIndex].channels[j].
4492 dwellTimeMs = active_max_chn_time;
4493 }
4494
4495 hddLog(LOG1,
4496 "Channel %u Passive %u Dwell time %u ms",
4497 pReqMsg->buckets[bktIndex].channels[j].channel,
4498 pReqMsg->buckets[bktIndex].channels[j].passive,
4499 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4500 }
4501
4502 bktIndex++;
4503 continue;
4504 }
4505
4506 /* Parse and fetch number of channels */
4507 if (!bucket[
4508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4509 hddLog(LOGE, FL("attr num channels failed"));
4510 return -EINVAL;
4511 }
4512
4513 pReqMsg->buckets[bktIndex].numChannels =
4514 nla_get_u32(bucket[
4515 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4516 hddLog(LOG1, FL("num channels %d"),
4517 pReqMsg->buckets[bktIndex].numChannels);
4518
4519 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4520 hddLog(LOGE, FL("attr channel spec failed"));
4521 return -EINVAL;
4522 }
4523
4524 j = 0;
4525 nla_for_each_nested(channels,
4526 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4527 if (nla_parse(channel,
4528 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4529 nla_data(channels), nla_len(channels),
4530 wlan_hdd_extscan_config_policy)) {
4531 hddLog(LOGE, FL("nla_parse failed"));
4532 return -EINVAL;
4533 }
4534
4535 /* Parse and fetch channel */
4536 if (!channel[
4537 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4538 hddLog(LOGE, FL("attr channel failed"));
4539 return -EINVAL;
4540 }
4541 pReqMsg->buckets[bktIndex].channels[j].channel =
4542 nla_get_u32(channel[
4543 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4544 hddLog(LOG1, FL("channel %u"),
4545 pReqMsg->buckets[bktIndex].channels[j].channel);
4546
4547 /* Parse and fetch dwell time */
4548 if (!channel[
4549 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4550 hddLog(LOGE, FL("attr dwelltime failed"));
4551 return -EINVAL;
4552 }
4553 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4554 nla_get_u32(channel[
4555 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4556
4557 hddLog(LOG1, FL("Dwell time (%u ms)"),
4558 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4559
4560
4561 /* Parse and fetch channel spec passive */
4562 if (!channel[
4563 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4564 hddLog(LOGE,
4565 FL("attr channel spec passive failed"));
4566 return -EINVAL;
4567 }
4568 pReqMsg->buckets[bktIndex].channels[j].passive =
4569 nla_get_u8(channel[
4570 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4571 hddLog(LOG1, FL("Chnl spec passive %u"),
4572 pReqMsg->buckets[bktIndex].channels[j].passive);
4573
4574 j++;
4575 }
4576
4577 bktIndex++;
4578 }
4579
4580 return 0;
4581}
4582
4583
4584/*
4585 * define short names for the global vendor params
4586 * used by wlan_hdd_cfg80211_extscan_start()
4587 */
4588#define PARAM_MAX \
4589QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4590#define PARAM_REQUEST_ID \
4591QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4592#define PARAM_BASE_PERIOD \
4593QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4594#define PARAM_MAX_AP_PER_SCAN \
4595QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4596#define PARAM_RPT_THRHLD_PERCENT \
4597QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4598#define PARAM_RPT_THRHLD_NUM_SCANS \
4599QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4600#define PARAM_NUM_BUCKETS \
4601QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4602
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304603static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304604 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304605 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304606{
Dino Myclee8843b32014-07-04 14:21:45 +05304607 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304608 struct net_device *dev = wdev->netdev;
4609 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4610 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4611 struct nlattr *tb[PARAM_MAX + 1];
4612 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304613 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304614 tANI_U32 request_id;
4615 struct hdd_ext_scan_context *context;
4616 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304617
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304618 ENTER();
4619
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304620 if (VOS_FTM_MODE == hdd_get_conparam()) {
4621 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4622 return -EINVAL;
4623 }
4624
Dino Mycle6fb96c12014-06-10 11:52:40 +05304625 status = wlan_hdd_validate_context(pHddCtx);
4626 if (0 != status)
4627 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304628 return -EINVAL;
4629 }
Dino Myclee8843b32014-07-04 14:21:45 +05304630 /* check the EXTScan Capability */
4631 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304632 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4633 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304634 {
4635 hddLog(VOS_TRACE_LEVEL_ERROR,
4636 FL("EXTScan not enabled/supported by Firmware"));
4637 return -EINVAL;
4638 }
4639
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304640 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304641 data, dataLen,
4642 wlan_hdd_extscan_config_policy)) {
4643 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4644 return -EINVAL;
4645 }
4646
4647 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304648 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304649 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4650 return -EINVAL;
4651 }
4652
Dino Myclee8843b32014-07-04 14:21:45 +05304653 pReqMsg = (tpSirEXTScanStartReqParams)
4654 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304655 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4657 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304658 }
4659
4660 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304661 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304662 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4663
4664 pReqMsg->sessionId = pAdapter->sessionId;
4665 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4666
4667 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304668 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304669 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4670 goto fail;
4671 }
4672 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304673 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304674 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4675 pReqMsg->basePeriod);
4676
4677 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304678 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4680 goto fail;
4681 }
4682 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304683 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304684 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4685 pReqMsg->maxAPperScan);
4686
4687 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304688 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4690 goto fail;
4691 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304692 pReqMsg->reportThresholdPercent = nla_get_u8(
4693 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304694 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304695 pReqMsg->reportThresholdPercent);
4696
4697 /* Parse and fetch report threshold num scans */
4698 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4699 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4700 goto fail;
4701 }
4702 pReqMsg->reportThresholdNumScans = nla_get_u8(
4703 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4704 hddLog(LOG1, FL("Report Threshold num scans %d"),
4705 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304706
4707 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304708 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304709 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4710 goto fail;
4711 }
4712 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304713 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304714 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4715 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4716 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4717 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4718 }
4719 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4720 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304721
Dino Mycle6fb96c12014-06-10 11:52:40 +05304722 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4723 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4724 goto fail;
4725 }
4726
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304727 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304728
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304729 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4730 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304731
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304732 context = &pHddCtx->ext_scan_context;
4733 spin_lock(&hdd_context_lock);
4734 INIT_COMPLETION(context->response_event);
4735 context->request_id = request_id = pReqMsg->requestId;
4736 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304737
Dino Mycle6fb96c12014-06-10 11:52:40 +05304738 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4739 if (!HAL_STATUS_SUCCESS(status)) {
4740 hddLog(VOS_TRACE_LEVEL_ERROR,
4741 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304742 goto fail;
4743 }
4744
Srinivas Dasari91727c12016-03-23 17:59:06 +05304745 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4746
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304747 /* request was sent -- wait for the response */
4748 rc = wait_for_completion_timeout(&context->response_event,
4749 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4750
4751 if (!rc) {
4752 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4753 retval = -ETIMEDOUT;
4754 } else {
4755 spin_lock(&hdd_context_lock);
4756 if (context->request_id == request_id)
4757 retval = context->response_status;
4758 else
4759 retval = -EINVAL;
4760 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304761 }
4762
Dino Myclee8843b32014-07-04 14:21:45 +05304763 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304764 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304765 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304766
4767fail:
4768 vos_mem_free(pReqMsg);
4769 return -EINVAL;
4770}
4771
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304772/*
4773 * done with short names for the global vendor params
4774 * used by wlan_hdd_cfg80211_extscan_start()
4775 */
4776#undef PARAM_MAX
4777#undef PARAM_REQUEST_ID
4778#undef PARAM_BASE_PERIOD
4779#undef PARAMS_MAX_AP_PER_SCAN
4780#undef PARAMS_RPT_THRHLD_PERCENT
4781#undef PARAMS_RPT_THRHLD_NUM_SCANS
4782#undef PARAMS_NUM_BUCKETS
4783
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304784static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4785 struct wireless_dev *wdev,
4786 const void *data, int dataLen)
4787{
4788 int ret = 0;
4789
4790 vos_ssr_protect(__func__);
4791 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4792 vos_ssr_unprotect(__func__);
4793
4794 return ret;
4795}
4796
4797static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304798 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304799 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304800{
Dino Myclee8843b32014-07-04 14:21:45 +05304801 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304802 struct net_device *dev = wdev->netdev;
4803 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4804 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4805 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4806 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304807 int retval;
4808 unsigned long rc;
4809 struct hdd_ext_scan_context *context;
4810 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304811
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304812 ENTER();
4813
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304814 if (VOS_FTM_MODE == hdd_get_conparam()) {
4815 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4816 return -EINVAL;
4817 }
4818
Dino Mycle6fb96c12014-06-10 11:52:40 +05304819 status = wlan_hdd_validate_context(pHddCtx);
4820 if (0 != status)
4821 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304822 return -EINVAL;
4823 }
Dino Myclee8843b32014-07-04 14:21:45 +05304824 /* check the EXTScan Capability */
4825 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304826 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4827 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304828 {
4829 hddLog(VOS_TRACE_LEVEL_ERROR,
4830 FL("EXTScan not enabled/supported by Firmware"));
4831 return -EINVAL;
4832 }
4833
Dino Mycle6fb96c12014-06-10 11:52:40 +05304834 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4835 data, dataLen,
4836 wlan_hdd_extscan_config_policy)) {
4837 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4838 return -EINVAL;
4839 }
4840
4841 /* Parse and fetch request Id */
4842 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4843 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4844 return -EINVAL;
4845 }
4846
Dino Myclee8843b32014-07-04 14:21:45 +05304847 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304848 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304849 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304850
Dino Myclee8843b32014-07-04 14:21:45 +05304851 reqMsg.sessionId = pAdapter->sessionId;
4852 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304853
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304854 context = &pHddCtx->ext_scan_context;
4855 spin_lock(&hdd_context_lock);
4856 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304857 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304858 spin_unlock(&hdd_context_lock);
4859
Dino Myclee8843b32014-07-04 14:21:45 +05304860 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304861 if (!HAL_STATUS_SUCCESS(status)) {
4862 hddLog(VOS_TRACE_LEVEL_ERROR,
4863 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304864 return -EINVAL;
4865 }
4866
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304867 /* request was sent -- wait for the response */
4868 rc = wait_for_completion_timeout(&context->response_event,
4869 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4870
4871 if (!rc) {
4872 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4873 retval = -ETIMEDOUT;
4874 } else {
4875 spin_lock(&hdd_context_lock);
4876 if (context->request_id == request_id)
4877 retval = context->response_status;
4878 else
4879 retval = -EINVAL;
4880 spin_unlock(&hdd_context_lock);
4881 }
4882
4883 return retval;
4884
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304885 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304886 return 0;
4887}
4888
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304889static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4890 struct wireless_dev *wdev,
4891 const void *data, int dataLen)
4892{
4893 int ret = 0;
4894
4895 vos_ssr_protect(__func__);
4896 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4897 vos_ssr_unprotect(__func__);
4898
4899 return ret;
4900}
4901
4902static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304903 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304904 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304905{
Dino Myclee8843b32014-07-04 14:21:45 +05304906 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304907 struct net_device *dev = wdev->netdev;
4908 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4909 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4910 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4911 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304912 struct hdd_ext_scan_context *context;
4913 tANI_U32 request_id;
4914 unsigned long rc;
4915 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304916
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304917 ENTER();
4918
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304919 if (VOS_FTM_MODE == hdd_get_conparam()) {
4920 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4921 return -EINVAL;
4922 }
4923
Dino Mycle6fb96c12014-06-10 11:52:40 +05304924 status = wlan_hdd_validate_context(pHddCtx);
4925 if (0 != status)
4926 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304927 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304928 return -EINVAL;
4929 }
Dino Myclee8843b32014-07-04 14:21:45 +05304930 /* check the EXTScan Capability */
4931 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304932 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4933 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304934 {
4935 hddLog(VOS_TRACE_LEVEL_ERROR,
4936 FL("EXTScan not enabled/supported by Firmware"));
4937 return -EINVAL;
4938 }
4939
Dino Mycle6fb96c12014-06-10 11:52:40 +05304940 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4941 data, dataLen,
4942 wlan_hdd_extscan_config_policy)) {
4943 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4944 return -EINVAL;
4945 }
4946
4947 /* Parse and fetch request Id */
4948 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4950 return -EINVAL;
4951 }
4952
Dino Myclee8843b32014-07-04 14:21:45 +05304953 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304954 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304955 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304956
Dino Myclee8843b32014-07-04 14:21:45 +05304957 reqMsg.sessionId = pAdapter->sessionId;
4958 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304959
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304960 context = &pHddCtx->ext_scan_context;
4961 spin_lock(&hdd_context_lock);
4962 INIT_COMPLETION(context->response_event);
4963 context->request_id = request_id = reqMsg.requestId;
4964 spin_unlock(&hdd_context_lock);
4965
Dino Myclee8843b32014-07-04 14:21:45 +05304966 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304967 if (!HAL_STATUS_SUCCESS(status)) {
4968 hddLog(VOS_TRACE_LEVEL_ERROR,
4969 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304970 return -EINVAL;
4971 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304972
4973 /* request was sent -- wait for the response */
4974 rc = wait_for_completion_timeout(&context->response_event,
4975 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4976 if (!rc) {
4977 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4978 retval = -ETIMEDOUT;
4979 } else {
4980 spin_lock(&hdd_context_lock);
4981 if (context->request_id == request_id)
4982 retval = context->response_status;
4983 else
4984 retval = -EINVAL;
4985 spin_unlock(&hdd_context_lock);
4986 }
4987
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304988 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304989 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304990}
4991
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304992static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4993 struct wireless_dev *wdev,
4994 const void *data, int dataLen)
4995{
4996 int ret = 0;
4997
4998 vos_ssr_protect(__func__);
4999 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5000 vos_ssr_unprotect(__func__);
5001
5002 return ret;
5003}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305004#endif /* WLAN_FEATURE_EXTSCAN */
5005
Atul Mittal115287b2014-07-08 13:26:33 +05305006/*EXT TDLS*/
5007static const struct nla_policy
5008wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5009{
5010 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5011 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5012 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5013 {.type = NLA_S32 },
5014 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5015 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5016
5017};
5018
5019static const struct nla_policy
5020wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5021{
5022 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5023
5024};
5025
5026static const struct nla_policy
5027wlan_hdd_tdls_config_state_change_policy[
5028 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5029{
5030 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
5031 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5032 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305033 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5034 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5035 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305036
5037};
5038
5039static const struct nla_policy
5040wlan_hdd_tdls_config_get_status_policy[
5041 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5042{
5043 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5044 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5045 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305046 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5047 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5048 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305049
5050};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305051
5052static const struct nla_policy
5053wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5054{
5055 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5056};
5057
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305058static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305059 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305060 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305061 int data_len)
5062{
5063
5064 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5065 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5066
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305067 ENTER();
5068
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305069 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305070 return -EINVAL;
5071 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305072 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305073 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305074 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305075 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305076 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305077 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305078 return -ENOTSUPP;
5079 }
5080
5081 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5082 data, data_len, wlan_hdd_mac_config)) {
5083 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5084 return -EINVAL;
5085 }
5086
5087 /* Parse and fetch mac address */
5088 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5089 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5090 return -EINVAL;
5091 }
5092
5093 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5094 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5095 VOS_MAC_ADDR_LAST_3_BYTES);
5096
Siddharth Bhal76972212014-10-15 16:22:51 +05305097 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5098
5099 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305100 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5101 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305102 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5103 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5104 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5105 {
5106 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5107 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5108 VOS_MAC_ADDRESS_LEN);
5109 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305110 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305111
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305112 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5113 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305114
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305115 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305116 return 0;
5117}
5118
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305119static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5120 struct wireless_dev *wdev,
5121 const void *data,
5122 int data_len)
5123{
5124 int ret = 0;
5125
5126 vos_ssr_protect(__func__);
5127 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5128 vos_ssr_unprotect(__func__);
5129
5130 return ret;
5131}
5132
5133static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305134 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305135 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305136 int data_len)
5137{
5138 u8 peer[6] = {0};
5139 struct net_device *dev = wdev->netdev;
5140 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5141 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5142 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5143 eHalStatus ret;
5144 tANI_S32 state;
5145 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305146 tANI_S32 global_operating_class = 0;
5147 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305148 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305149 int retVal;
5150
5151 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305152
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305153 if (!pAdapter) {
5154 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5155 return -EINVAL;
5156 }
5157
Atul Mittal115287b2014-07-08 13:26:33 +05305158 ret = wlan_hdd_validate_context(pHddCtx);
5159 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305161 return -EINVAL;
5162 }
5163 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305164 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305165 return -ENOTSUPP;
5166 }
5167 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5168 data, data_len,
5169 wlan_hdd_tdls_config_get_status_policy)) {
5170 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5171 return -EINVAL;
5172 }
5173
5174 /* Parse and fetch mac address */
5175 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5176 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5177 return -EINVAL;
5178 }
5179
5180 memcpy(peer, nla_data(
5181 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5182 sizeof(peer));
5183 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5184
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305185 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305186
Atul Mittal115287b2014-07-08 13:26:33 +05305187 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305188 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305189 NLMSG_HDRLEN);
5190
5191 if (!skb) {
5192 hddLog(VOS_TRACE_LEVEL_ERROR,
5193 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5194 return -EINVAL;
5195 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305196 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 +05305197 reason,
5198 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305199 global_operating_class,
5200 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305201 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305202 if (nla_put_s32(skb,
5203 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5204 state) ||
5205 nla_put_s32(skb,
5206 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5207 reason) ||
5208 nla_put_s32(skb,
5209 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5210 global_operating_class) ||
5211 nla_put_s32(skb,
5212 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5213 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305214
5215 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5216 goto nla_put_failure;
5217 }
5218
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305219 retVal = cfg80211_vendor_cmd_reply(skb);
5220 EXIT();
5221 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305222
5223nla_put_failure:
5224 kfree_skb(skb);
5225 return -EINVAL;
5226}
5227
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305228static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5229 struct wireless_dev *wdev,
5230 const void *data,
5231 int data_len)
5232{
5233 int ret = 0;
5234
5235 vos_ssr_protect(__func__);
5236 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5237 vos_ssr_unprotect(__func__);
5238
5239 return ret;
5240}
5241
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305242static int wlan_hdd_cfg80211_exttdls_callback(
5243#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5244 const tANI_U8* mac,
5245#else
5246 tANI_U8* mac,
5247#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305248 tANI_S32 state,
5249 tANI_S32 reason,
5250 void *ctx)
5251{
5252 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305253 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305254 tANI_S32 global_operating_class = 0;
5255 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305256 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305257
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305258 ENTER();
5259
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305260 if (!pAdapter) {
5261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5262 return -EINVAL;
5263 }
5264
5265 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305266 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305268 return -EINVAL;
5269 }
5270
5271 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305272 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305273 return -ENOTSUPP;
5274 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305275 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5276#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5277 NULL,
5278#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305279 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5280 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5281 GFP_KERNEL);
5282
5283 if (!skb) {
5284 hddLog(VOS_TRACE_LEVEL_ERROR,
5285 FL("cfg80211_vendor_event_alloc failed"));
5286 return -EINVAL;
5287 }
5288 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305289 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5290 reason,
5291 state,
5292 global_operating_class,
5293 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305294 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5295 MAC_ADDR_ARRAY(mac));
5296
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305297 if (nla_put(skb,
5298 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5299 VOS_MAC_ADDR_SIZE, mac) ||
5300 nla_put_s32(skb,
5301 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5302 state) ||
5303 nla_put_s32(skb,
5304 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5305 reason) ||
5306 nla_put_s32(skb,
5307 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5308 channel) ||
5309 nla_put_s32(skb,
5310 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5311 global_operating_class)
5312 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5314 goto nla_put_failure;
5315 }
5316
5317 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305318 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305319 return (0);
5320
5321nla_put_failure:
5322 kfree_skb(skb);
5323 return -EINVAL;
5324}
5325
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305326static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305327 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305328 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305329 int data_len)
5330{
5331 u8 peer[6] = {0};
5332 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305333 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5334 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5335 eHalStatus status;
5336 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305337 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305338 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305339
5340 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305341
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305342 if (!dev) {
5343 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5344 return -EINVAL;
5345 }
5346
5347 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5348 if (!pAdapter) {
5349 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5350 return -EINVAL;
5351 }
5352
Atul Mittal115287b2014-07-08 13:26:33 +05305353 status = wlan_hdd_validate_context(pHddCtx);
5354 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305356 return -EINVAL;
5357 }
5358 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305359 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305360 return -ENOTSUPP;
5361 }
5362 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5363 data, data_len,
5364 wlan_hdd_tdls_config_enable_policy)) {
5365 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5366 return -EINVAL;
5367 }
5368
5369 /* Parse and fetch mac address */
5370 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5371 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5372 return -EINVAL;
5373 }
5374
5375 memcpy(peer, nla_data(
5376 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5377 sizeof(peer));
5378 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5379
5380 /* Parse and fetch channel */
5381 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5382 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5383 return -EINVAL;
5384 }
5385 pReqMsg.channel = nla_get_s32(
5386 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5387 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5388
5389 /* Parse and fetch global operating class */
5390 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5391 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5392 return -EINVAL;
5393 }
5394 pReqMsg.global_operating_class = nla_get_s32(
5395 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5396 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5397 pReqMsg.global_operating_class);
5398
5399 /* Parse and fetch latency ms */
5400 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5402 return -EINVAL;
5403 }
5404 pReqMsg.max_latency_ms = nla_get_s32(
5405 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5406 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5407 pReqMsg.max_latency_ms);
5408
5409 /* Parse and fetch required bandwidth kbps */
5410 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5411 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5412 return -EINVAL;
5413 }
5414
5415 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5416 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5417 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5418 pReqMsg.min_bandwidth_kbps);
5419
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305420 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305421 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305422 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305423 wlan_hdd_cfg80211_exttdls_callback);
5424
5425 EXIT();
5426 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305427}
5428
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305429static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5430 struct wireless_dev *wdev,
5431 const void *data,
5432 int data_len)
5433{
5434 int ret = 0;
5435
5436 vos_ssr_protect(__func__);
5437 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5438 vos_ssr_unprotect(__func__);
5439
5440 return ret;
5441}
5442
5443static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305444 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305445 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305446 int data_len)
5447{
5448 u8 peer[6] = {0};
5449 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305450 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5451 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5452 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305453 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305454 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305455
5456 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305457
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305458 if (!dev) {
5459 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5460 return -EINVAL;
5461 }
5462
5463 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5464 if (!pAdapter) {
5465 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5466 return -EINVAL;
5467 }
5468
Atul Mittal115287b2014-07-08 13:26:33 +05305469 status = wlan_hdd_validate_context(pHddCtx);
5470 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305472 return -EINVAL;
5473 }
5474 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305476 return -ENOTSUPP;
5477 }
5478 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5479 data, data_len,
5480 wlan_hdd_tdls_config_disable_policy)) {
5481 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5482 return -EINVAL;
5483 }
5484 /* Parse and fetch mac address */
5485 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5486 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5487 return -EINVAL;
5488 }
5489
5490 memcpy(peer, nla_data(
5491 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5492 sizeof(peer));
5493 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5494
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305495 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5496
5497 EXIT();
5498 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305499}
5500
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305501static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5502 struct wireless_dev *wdev,
5503 const void *data,
5504 int data_len)
5505{
5506 int ret = 0;
5507
5508 vos_ssr_protect(__func__);
5509 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5510 vos_ssr_unprotect(__func__);
5511
5512 return ret;
5513}
5514
Dasari Srinivas7875a302014-09-26 17:50:57 +05305515static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305516__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305517 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305518 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305519{
5520 struct net_device *dev = wdev->netdev;
5521 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5522 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5523 struct sk_buff *skb = NULL;
5524 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305525 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305526
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305527 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305528
5529 ret = wlan_hdd_validate_context(pHddCtx);
5530 if (0 != ret)
5531 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305532 return ret;
5533 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305534 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5535 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5536 fset |= WIFI_FEATURE_INFRA;
5537 }
5538
5539 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5540 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5541 fset |= WIFI_FEATURE_INFRA_5G;
5542 }
5543
5544#ifdef WLAN_FEATURE_P2P
5545 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5546 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5547 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5548 fset |= WIFI_FEATURE_P2P;
5549 }
5550#endif
5551
5552 /* Soft-AP is supported currently by default */
5553 fset |= WIFI_FEATURE_SOFT_AP;
5554
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305555 /* HOTSPOT is a supplicant feature, enable it by default */
5556 fset |= WIFI_FEATURE_HOTSPOT;
5557
Dasari Srinivas7875a302014-09-26 17:50:57 +05305558#ifdef WLAN_FEATURE_EXTSCAN
5559 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305560 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5561 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5562 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305563 fset |= WIFI_FEATURE_EXTSCAN;
5564 }
5565#endif
5566
Dasari Srinivas7875a302014-09-26 17:50:57 +05305567 if (sme_IsFeatureSupportedByFW(NAN)) {
5568 hddLog(LOG1, FL("NAN is supported by firmware"));
5569 fset |= WIFI_FEATURE_NAN;
5570 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305571
5572 /* D2D RTT is not supported currently by default */
5573 if (sme_IsFeatureSupportedByFW(RTT)) {
5574 hddLog(LOG1, FL("RTT is supported by firmware"));
5575 fset |= WIFI_FEATURE_D2AP_RTT;
5576 }
5577
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305578 if (sme_IsFeatureSupportedByFW(RTT3)) {
5579 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5580 fset |= WIFI_FEATURE_RTT3;
5581 }
5582
Dasari Srinivas7875a302014-09-26 17:50:57 +05305583#ifdef FEATURE_WLAN_BATCH_SCAN
5584 if (fset & WIFI_FEATURE_EXTSCAN) {
5585 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5586 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5587 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5588 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5589 fset |= WIFI_FEATURE_BATCH_SCAN;
5590 }
5591#endif
5592
5593#ifdef FEATURE_WLAN_SCAN_PNO
5594 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5595 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5596 hddLog(LOG1, FL("PNO is supported by firmware"));
5597 fset |= WIFI_FEATURE_PNO;
5598 }
5599#endif
5600
5601 /* STA+STA is supported currently by default */
5602 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5603
5604#ifdef FEATURE_WLAN_TDLS
5605 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5606 sme_IsFeatureSupportedByFW(TDLS)) {
5607 hddLog(LOG1, FL("TDLS is supported by firmware"));
5608 fset |= WIFI_FEATURE_TDLS;
5609 }
5610
5611 /* TDLS_OFFCHANNEL is not supported currently by default */
5612#endif
5613
5614#ifdef WLAN_AP_STA_CONCURRENCY
5615 /* AP+STA concurrency is supported currently by default */
5616 fset |= WIFI_FEATURE_AP_STA;
5617#endif
5618
Mukul Sharma5add0532015-08-17 15:57:47 +05305619#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5620 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5621 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5622#endif
5623
Dasari Srinivas7875a302014-09-26 17:50:57 +05305624 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5625 NLMSG_HDRLEN);
5626
5627 if (!skb) {
5628 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5629 return -EINVAL;
5630 }
5631 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5632
5633 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5634 hddLog(LOGE, FL("nla put fail"));
5635 goto nla_put_failure;
5636 }
5637
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305638 ret = cfg80211_vendor_cmd_reply(skb);
5639 EXIT();
5640 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305641
5642nla_put_failure:
5643 kfree_skb(skb);
5644 return -EINVAL;
5645}
5646
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305647static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305648wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5649 struct wireless_dev *wdev,
5650 const void *data, int data_len)
5651{
5652 int ret = 0;
5653
5654 vos_ssr_protect(__func__);
5655 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5656 vos_ssr_unprotect(__func__);
5657
5658 return ret;
5659}
5660
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305661
5662static const struct
5663nla_policy
5664qca_wlan_vendor_wifi_logger_get_ring_data_policy
5665[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5666 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5667 = {.type = NLA_U32 },
5668};
5669
5670static int
5671 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5672 struct wireless_dev *wdev,
5673 const void *data,
5674 int data_len)
5675{
5676 int ret;
5677 VOS_STATUS status;
5678 uint32_t ring_id;
5679 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5680 struct nlattr *tb
5681 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5682
5683 ENTER();
5684
5685 ret = wlan_hdd_validate_context(hdd_ctx);
5686 if (0 != ret) {
5687 return ret;
5688 }
5689
5690 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5691 data, data_len,
5692 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5693 hddLog(LOGE, FL("Invalid attribute"));
5694 return -EINVAL;
5695 }
5696
5697 /* Parse and fetch ring id */
5698 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5699 hddLog(LOGE, FL("attr ATTR failed"));
5700 return -EINVAL;
5701 }
5702
5703 ring_id = nla_get_u32(
5704 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5705
5706 hddLog(LOG1, FL("Bug report triggered by framework"));
5707
5708 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5709 WLAN_LOG_INDICATOR_FRAMEWORK,
5710 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305711 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305712 );
5713 if (VOS_STATUS_SUCCESS != status) {
5714 hddLog(LOGE, FL("Failed to trigger bug report"));
5715
5716 return -EINVAL;
5717 }
5718
5719 return 0;
5720
5721
5722}
5723
5724
5725static int
5726 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5727 struct wireless_dev *wdev,
5728 const void *data,
5729 int data_len)
5730{
5731 int ret = 0;
5732
5733 vos_ssr_protect(__func__);
5734 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5735 wdev, data, data_len);
5736 vos_ssr_unprotect(__func__);
5737
5738 return ret;
5739
5740}
5741
5742
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305743static int
5744__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305745 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305746 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305747{
5748 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5749 uint8_t i, feature_sets, max_feature_sets;
5750 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5751 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305752 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5753 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305754
5755 ENTER();
5756
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305757 ret = wlan_hdd_validate_context(pHddCtx);
5758 if (0 != ret)
5759 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305760 return ret;
5761 }
5762
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305763 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5764 data, data_len, NULL)) {
5765 hddLog(LOGE, FL("Invalid ATTR"));
5766 return -EINVAL;
5767 }
5768
5769 /* Parse and fetch max feature set */
5770 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5771 hddLog(LOGE, FL("Attr max feature set size failed"));
5772 return -EINVAL;
5773 }
5774 max_feature_sets = nla_get_u32(
5775 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5776 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5777
5778 /* Fill feature combination matrix */
5779 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305780 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5781 WIFI_FEATURE_P2P;
5782
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305783 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5784 WIFI_FEATURE_SOFT_AP;
5785
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305786 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5787 WIFI_FEATURE_SOFT_AP;
5788
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305789 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5790 WIFI_FEATURE_SOFT_AP |
5791 WIFI_FEATURE_P2P;
5792
5793 /* Add more feature combinations here */
5794
5795 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5796 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5797 hddLog(LOG1, "Feature set matrix");
5798 for (i = 0; i < feature_sets; i++)
5799 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5800
5801 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5802 sizeof(u32) * feature_sets +
5803 NLMSG_HDRLEN);
5804
5805 if (reply_skb) {
5806 if (nla_put_u32(reply_skb,
5807 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5808 feature_sets) ||
5809 nla_put(reply_skb,
5810 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5811 sizeof(u32) * feature_sets, feature_set_matrix)) {
5812 hddLog(LOGE, FL("nla put fail"));
5813 kfree_skb(reply_skb);
5814 return -EINVAL;
5815 }
5816
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305817 ret = cfg80211_vendor_cmd_reply(reply_skb);
5818 EXIT();
5819 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305820 }
5821 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5822 return -ENOMEM;
5823
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305824}
5825
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305826static int
5827wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5828 struct wireless_dev *wdev,
5829 const void *data, int data_len)
5830{
5831 int ret = 0;
5832
5833 vos_ssr_protect(__func__);
5834 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5835 data_len);
5836 vos_ssr_unprotect(__func__);
5837
5838 return ret;
5839}
5840
c_manjeecfd1efb2015-09-25 19:32:34 +05305841
5842static int
5843__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5844 struct wireless_dev *wdev,
5845 const void *data, int data_len)
5846{
5847 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5848 int ret;
5849 ENTER();
5850
5851 ret = wlan_hdd_validate_context(pHddCtx);
5852 if (0 != ret)
5853 {
5854 return ret;
5855 }
5856
5857 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5858 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5859 {
5860 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5861 return -EINVAL;
5862 }
5863 /*call common API for FW mem dump req*/
5864 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5865
Abhishek Singhc783fa72015-12-09 18:07:34 +05305866 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305867 {
5868 /*indicate to userspace the status of fw mem dump */
5869 wlan_indicate_mem_dump_complete(true);
5870 }
5871 else
5872 {
5873 /*else send failure to userspace */
5874 wlan_indicate_mem_dump_complete(false);
5875 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305876 EXIT();
5877 return ret;
5878}
5879
5880/**
5881 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5882 * @wiphy: pointer to wireless wiphy structure.
5883 * @wdev: pointer to wireless_dev structure.
5884 * @data: Pointer to the NL data.
5885 * @data_len:Length of @data
5886 *
5887 * This is called when wlan driver needs to get the firmware memory dump
5888 * via vendor specific command.
5889 *
5890 * Return: 0 on success, error number otherwise.
5891 */
5892
5893static int
5894wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5895 struct wireless_dev *wdev,
5896 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305897{
5898 int ret = 0;
5899 vos_ssr_protect(__func__);
5900 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5901 data_len);
5902 vos_ssr_unprotect(__func__);
5903 return ret;
5904}
c_manjeecfd1efb2015-09-25 19:32:34 +05305905
Sushant Kaushik8e644982015-09-23 12:18:54 +05305906static const struct
5907nla_policy
5908qca_wlan_vendor_wifi_logger_start_policy
5909[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5910 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5911 = {.type = NLA_U32 },
5912 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5913 = {.type = NLA_U32 },
5914 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5915 = {.type = NLA_U32 },
5916};
5917
5918/**
5919 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5920 * or disable the collection of packet statistics from the firmware
5921 * @wiphy: WIPHY structure pointer
5922 * @wdev: Wireless device structure pointer
5923 * @data: Pointer to the data received
5924 * @data_len: Length of the data received
5925 *
5926 * This function is used to enable or disable the collection of packet
5927 * statistics from the firmware
5928 *
5929 * Return: 0 on success and errno on failure
5930 */
5931static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5932 struct wireless_dev *wdev,
5933 const void *data,
5934 int data_len)
5935{
5936 eHalStatus status;
5937 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5938 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5939 tAniWifiStartLog start_log;
5940
5941 status = wlan_hdd_validate_context(hdd_ctx);
5942 if (0 != status) {
5943 return -EINVAL;
5944 }
5945
5946 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5947 data, data_len,
5948 qca_wlan_vendor_wifi_logger_start_policy)) {
5949 hddLog(LOGE, FL("Invalid attribute"));
5950 return -EINVAL;
5951 }
5952
5953 /* Parse and fetch ring id */
5954 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5955 hddLog(LOGE, FL("attr ATTR failed"));
5956 return -EINVAL;
5957 }
5958 start_log.ringId = nla_get_u32(
5959 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5960 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5961
5962 /* Parse and fetch verbose level */
5963 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5964 hddLog(LOGE, FL("attr verbose_level failed"));
5965 return -EINVAL;
5966 }
5967 start_log.verboseLevel = nla_get_u32(
5968 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5969 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5970
5971 /* Parse and fetch flag */
5972 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5973 hddLog(LOGE, FL("attr flag failed"));
5974 return -EINVAL;
5975 }
5976 start_log.flag = nla_get_u32(
5977 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5978 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5979
5980 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305981 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5982 !vos_isPktStatsEnabled()))
5983
Sushant Kaushik8e644982015-09-23 12:18:54 +05305984 {
5985 hddLog(LOGE, FL("per pkt stats not enabled"));
5986 return -EINVAL;
5987 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305988
Sushant Kaushik33200572015-08-05 16:46:20 +05305989 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305990 return 0;
5991}
5992
5993/**
5994 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5995 * or disable the collection of packet statistics from the firmware
5996 * @wiphy: WIPHY structure pointer
5997 * @wdev: Wireless device structure pointer
5998 * @data: Pointer to the data received
5999 * @data_len: Length of the data received
6000 *
6001 * This function is used to enable or disable the collection of packet
6002 * statistics from the firmware
6003 *
6004 * Return: 0 on success and errno on failure
6005 */
6006static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6007 struct wireless_dev *wdev,
6008 const void *data,
6009 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306010{
6011 int ret = 0;
6012
6013 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306014
6015 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6016 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306017 vos_ssr_unprotect(__func__);
6018
6019 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306020}
6021
6022
Agarwal Ashish738843c2014-09-25 12:27:56 +05306023static const struct nla_policy
6024wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6025 +1] =
6026{
6027 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6028};
6029
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306030static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306031 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306032 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306033 int data_len)
6034{
6035 struct net_device *dev = wdev->netdev;
6036 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6037 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6038 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6039 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6040 eHalStatus status;
6041 u32 dfsFlag = 0;
6042
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306043 ENTER();
6044
Agarwal Ashish738843c2014-09-25 12:27:56 +05306045 status = wlan_hdd_validate_context(pHddCtx);
6046 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306047 return -EINVAL;
6048 }
6049 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6050 data, data_len,
6051 wlan_hdd_set_no_dfs_flag_config_policy)) {
6052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6053 return -EINVAL;
6054 }
6055
6056 /* Parse and fetch required bandwidth kbps */
6057 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6058 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6059 return -EINVAL;
6060 }
6061
6062 dfsFlag = nla_get_u32(
6063 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6064 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6065 dfsFlag);
6066
6067 pHddCtx->disable_dfs_flag = dfsFlag;
6068
6069 sme_disable_dfs_channel(hHal, dfsFlag);
6070 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306071
6072 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306073 return 0;
6074}
Atul Mittal115287b2014-07-08 13:26:33 +05306075
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306076static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6077 struct wireless_dev *wdev,
6078 const void *data,
6079 int data_len)
6080{
6081 int ret = 0;
6082
6083 vos_ssr_protect(__func__);
6084 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6085 vos_ssr_unprotect(__func__);
6086
6087 return ret;
6088
6089}
6090
Mukul Sharma2a271632014-10-13 14:59:01 +05306091const struct
6092nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6093{
6094 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6095 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6096};
6097
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306098static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306099 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306100{
6101
6102 u8 bssid[6] = {0};
6103 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6104 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6105 eHalStatus status = eHAL_STATUS_SUCCESS;
6106 v_U32_t isFwrRoamEnabled = FALSE;
6107 int ret;
6108
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306109 ENTER();
6110
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306111 ret = wlan_hdd_validate_context(pHddCtx);
6112 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306113 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306114 }
6115
6116 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6117 data, data_len,
6118 qca_wlan_vendor_attr);
6119 if (ret){
6120 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6121 return -EINVAL;
6122 }
6123
6124 /* Parse and fetch Enable flag */
6125 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6126 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6127 return -EINVAL;
6128 }
6129
6130 isFwrRoamEnabled = nla_get_u32(
6131 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6132
6133 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6134
6135 /* Parse and fetch bssid */
6136 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6137 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6138 return -EINVAL;
6139 }
6140
6141 memcpy(bssid, nla_data(
6142 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6143 sizeof(bssid));
6144 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6145
6146 //Update roaming
6147 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306148 if (!HAL_STATUS_SUCCESS(status)) {
6149 hddLog(LOGE,
6150 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6151 return -EINVAL;
6152 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306153 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306154 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306155}
6156
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306157static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6158 struct wireless_dev *wdev, const void *data, int data_len)
6159{
6160 int ret = 0;
6161
6162 vos_ssr_protect(__func__);
6163 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6164 vos_ssr_unprotect(__func__);
6165
6166 return ret;
6167}
6168
Sushant Kaushik847890c2015-09-28 16:05:17 +05306169static const struct
6170nla_policy
6171qca_wlan_vendor_get_wifi_info_policy[
6172 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6173 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6174 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6175};
6176
6177
6178/**
6179 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6180 * @wiphy: pointer to wireless wiphy structure.
6181 * @wdev: pointer to wireless_dev structure.
6182 * @data: Pointer to the data to be passed via vendor interface
6183 * @data_len:Length of the data to be passed
6184 *
6185 * This is called when wlan driver needs to send wifi driver related info
6186 * (driver/fw version) to the user space application upon request.
6187 *
6188 * Return: Return the Success or Failure code.
6189 */
6190static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6191 struct wireless_dev *wdev,
6192 const void *data, int data_len)
6193{
6194 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6195 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6196 tSirVersionString version;
6197 uint32 version_len;
6198 uint8 attr;
6199 int status;
6200 struct sk_buff *reply_skb = NULL;
6201
6202 if (VOS_FTM_MODE == hdd_get_conparam()) {
6203 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6204 return -EINVAL;
6205 }
6206
6207 status = wlan_hdd_validate_context(hdd_ctx);
6208 if (0 != status) {
6209 hddLog(LOGE, FL("HDD context is not valid"));
6210 return -EINVAL;
6211 }
6212
6213 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6214 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6215 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6216 return -EINVAL;
6217 }
6218
6219 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6220 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6221 QWLAN_VERSIONSTR);
6222 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6223 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6224 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6225 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6226 hdd_ctx->fw_Version);
6227 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6228 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6229 } else {
6230 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6231 return -EINVAL;
6232 }
6233
6234 version_len = strlen(version);
6235 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6236 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6237 if (!reply_skb) {
6238 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6239 return -ENOMEM;
6240 }
6241
6242 if (nla_put(reply_skb, attr, version_len, version)) {
6243 hddLog(LOGE, FL("nla put fail"));
6244 kfree_skb(reply_skb);
6245 return -EINVAL;
6246 }
6247
6248 return cfg80211_vendor_cmd_reply(reply_skb);
6249}
6250
6251/**
6252 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6253 * @wiphy: pointer to wireless wiphy structure.
6254 * @wdev: pointer to wireless_dev structure.
6255 * @data: Pointer to the data to be passed via vendor interface
6256 * @data_len:Length of the data to be passed
6257 * @data_len: Length of the data received
6258 *
6259 * This function is used to enable or disable the collection of packet
6260 * statistics from the firmware
6261 *
6262 * Return: 0 on success and errno on failure
6263 */
6264
6265static int
6266wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6267 struct wireless_dev *wdev,
6268 const void *data, int data_len)
6269
6270
6271{
6272 int ret = 0;
6273
6274 vos_ssr_protect(__func__);
6275 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6276 wdev, data, data_len);
6277 vos_ssr_unprotect(__func__);
6278
6279 return ret;
6280}
6281
6282
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306283/*
6284 * define short names for the global vendor params
6285 * used by __wlan_hdd_cfg80211_monitor_rssi()
6286 */
6287#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6288#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6289#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6290#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6291#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6292
6293/**---------------------------------------------------------------------------
6294
6295 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6296 monitor start is completed successfully.
6297
6298 \return - None
6299
6300 --------------------------------------------------------------------------*/
6301void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6302{
6303 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6304
6305 if (NULL == pHddCtx)
6306 {
6307 hddLog(VOS_TRACE_LEVEL_ERROR,
6308 "%s: HDD context is NULL",__func__);
6309 return;
6310 }
6311
6312 if (VOS_STATUS_SUCCESS == status)
6313 {
6314 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6315 }
6316 else
6317 {
6318 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6319 }
6320
6321 return;
6322}
6323
6324/**---------------------------------------------------------------------------
6325
6326 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6327 stop is completed successfully.
6328
6329 \return - None
6330
6331 --------------------------------------------------------------------------*/
6332void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6333{
6334 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6335
6336 if (NULL == pHddCtx)
6337 {
6338 hddLog(VOS_TRACE_LEVEL_ERROR,
6339 "%s: HDD context is NULL",__func__);
6340 return;
6341 }
6342
6343 if (VOS_STATUS_SUCCESS == status)
6344 {
6345 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6346 }
6347 else
6348 {
6349 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6350 }
6351
6352 return;
6353}
6354
6355/**
6356 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6357 * @wiphy: Pointer to wireless phy
6358 * @wdev: Pointer to wireless device
6359 * @data: Pointer to data
6360 * @data_len: Data length
6361 *
6362 * Return: 0 on success, negative errno on failure
6363 */
6364
6365static int
6366__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6367 struct wireless_dev *wdev,
6368 const void *data,
6369 int data_len)
6370{
6371 struct net_device *dev = wdev->netdev;
6372 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6373 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6374 hdd_station_ctx_t *pHddStaCtx;
6375 struct nlattr *tb[PARAM_MAX + 1];
6376 tpSirRssiMonitorReq pReq;
6377 eHalStatus status;
6378 int ret;
6379 uint32_t control;
6380 static const struct nla_policy policy[PARAM_MAX + 1] = {
6381 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6382 [PARAM_CONTROL] = { .type = NLA_U32 },
6383 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6384 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6385 };
6386
6387 ENTER();
6388
6389 ret = wlan_hdd_validate_context(hdd_ctx);
6390 if (0 != ret) {
6391 return -EINVAL;
6392 }
6393
6394 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6395 hddLog(LOGE, FL("Not in Connected state!"));
6396 return -ENOTSUPP;
6397 }
6398
6399 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6400 hddLog(LOGE, FL("Invalid ATTR"));
6401 return -EINVAL;
6402 }
6403
6404 if (!tb[PARAM_REQUEST_ID]) {
6405 hddLog(LOGE, FL("attr request id failed"));
6406 return -EINVAL;
6407 }
6408
6409 if (!tb[PARAM_CONTROL]) {
6410 hddLog(LOGE, FL("attr control failed"));
6411 return -EINVAL;
6412 }
6413
6414 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6415
6416 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6417 if(NULL == pReq)
6418 {
6419 hddLog(LOGE,
6420 FL("vos_mem_alloc failed "));
6421 return eHAL_STATUS_FAILED_ALLOC;
6422 }
6423 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6424
6425 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6426 pReq->sessionId = pAdapter->sessionId;
6427 pReq->rssiMonitorCbContext = hdd_ctx;
6428 control = nla_get_u32(tb[PARAM_CONTROL]);
6429 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6430
6431 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6432 pReq->requestId, pReq->sessionId, control);
6433
6434 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6435 if (!tb[PARAM_MIN_RSSI]) {
6436 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306437 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306438 }
6439
6440 if (!tb[PARAM_MAX_RSSI]) {
6441 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306442 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306443 }
6444
6445 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6446 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6447 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6448
6449 if (!(pReq->minRssi < pReq->maxRssi)) {
6450 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6451 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306452 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306453 }
6454 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6455 pReq->minRssi, pReq->maxRssi);
6456 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6457
6458 }
6459 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6460 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6461 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6462 }
6463 else {
6464 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306465 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306466 }
6467
6468 if (!HAL_STATUS_SUCCESS(status)) {
6469 hddLog(LOGE,
6470 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306471 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306472 }
6473
6474 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306475fail:
6476 vos_mem_free(pReq);
6477 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306478}
6479
6480/*
6481 * done with short names for the global vendor params
6482 * used by __wlan_hdd_cfg80211_monitor_rssi()
6483 */
6484#undef PARAM_MAX
6485#undef PARAM_CONTROL
6486#undef PARAM_REQUEST_ID
6487#undef PARAM_MAX_RSSI
6488#undef PARAM_MIN_RSSI
6489
6490/**
6491 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6492 * @wiphy: wiphy structure pointer
6493 * @wdev: Wireless device structure pointer
6494 * @data: Pointer to the data received
6495 * @data_len: Length of @data
6496 *
6497 * Return: 0 on success; errno on failure
6498 */
6499static int
6500wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6501 const void *data, int data_len)
6502{
6503 int ret;
6504
6505 vos_ssr_protect(__func__);
6506 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6507 vos_ssr_unprotect(__func__);
6508
6509 return ret;
6510}
6511
6512/**
6513 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6514 * @hddctx: HDD context
6515 * @data: rssi breached event data
6516 *
6517 * This function reads the rssi breached event %data and fill in the skb with
6518 * NL attributes and send up the NL event.
6519 * This callback execute in atomic context and must not invoke any
6520 * blocking calls.
6521 *
6522 * Return: none
6523 */
6524void hdd_rssi_threshold_breached_cb(void *hddctx,
6525 struct rssi_breach_event *data)
6526{
6527 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6528 int status;
6529 struct sk_buff *skb;
6530
6531 ENTER();
6532 status = wlan_hdd_validate_context(pHddCtx);
6533
6534 if (0 != status) {
6535 return;
6536 }
6537
6538 if (!data) {
6539 hddLog(LOGE, FL("data is null"));
6540 return;
6541 }
6542
6543 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6544#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6545 NULL,
6546#endif
6547 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6548 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6549 GFP_KERNEL);
6550
6551 if (!skb) {
6552 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6553 return;
6554 }
6555
6556 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6557 data->request_id, data->curr_rssi);
6558 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6559 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6560
6561 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6562 data->request_id) ||
6563 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6564 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6565 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6566 data->curr_rssi)) {
6567 hddLog(LOGE, FL("nla put fail"));
6568 goto fail;
6569 }
6570
6571 cfg80211_vendor_event(skb, GFP_KERNEL);
6572 return;
6573
6574fail:
6575 kfree_skb(skb);
6576 return;
6577}
6578
6579
6580
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306581/**
6582 * __wlan_hdd_cfg80211_setband() - set band
6583 * @wiphy: Pointer to wireless phy
6584 * @wdev: Pointer to wireless device
6585 * @data: Pointer to data
6586 * @data_len: Data length
6587 *
6588 * Return: 0 on success, negative errno on failure
6589 */
6590static int
6591__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6592 struct wireless_dev *wdev,
6593 const void *data,
6594 int data_len)
6595{
6596 struct net_device *dev = wdev->netdev;
6597 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6598 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6599 int ret;
6600 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6601 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6602
6603 ENTER();
6604
6605 ret = wlan_hdd_validate_context(hdd_ctx);
6606 if (0 != ret) {
6607 hddLog(LOGE, FL("HDD context is not valid"));
6608 return ret;
6609 }
6610
6611 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6612 policy)) {
6613 hddLog(LOGE, FL("Invalid ATTR"));
6614 return -EINVAL;
6615 }
6616
6617 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6618 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6619 return -EINVAL;
6620 }
6621
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306622 hdd_ctx->isSetBandByNL = TRUE;
6623 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306624 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306625 hdd_ctx->isSetBandByNL = FALSE;
6626
6627 EXIT();
6628 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306629}
6630
6631/**
6632 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6633 * @wiphy: wiphy structure pointer
6634 * @wdev: Wireless device structure pointer
6635 * @data: Pointer to the data received
6636 * @data_len: Length of @data
6637 *
6638 * Return: 0 on success; errno on failure
6639 */
6640static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6641 struct wireless_dev *wdev,
6642 const void *data,
6643 int data_len)
6644{
6645 int ret = 0;
6646
6647 vos_ssr_protect(__func__);
6648 ret = __wlan_hdd_cfg80211_setband(wiphy,
6649 wdev, data, data_len);
6650 vos_ssr_unprotect(__func__);
6651
6652 return ret;
6653}
6654
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306655#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6656/**
6657 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6658 * @hdd_ctx: HDD context
6659 * @request_id: [input] request id
6660 * @pattern_id: [output] pattern id
6661 *
6662 * This function loops through request id to pattern id array
6663 * if the slot is available, store the request id and return pattern id
6664 * if entry exists, return the pattern id
6665 *
6666 * Return: 0 on success and errno on failure
6667 */
6668static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6669 uint32_t request_id,
6670 uint8_t *pattern_id)
6671{
6672 uint32_t i;
6673
6674 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6675 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6676 {
6677 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6678 {
6679 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6680 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6681 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6682 return 0;
6683 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6684 request_id) {
6685 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6686 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6687 return 0;
6688 }
6689 }
6690 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6691 return -EINVAL;
6692}
6693
6694/**
6695 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6696 * @hdd_ctx: HDD context
6697 * @request_id: [input] request id
6698 * @pattern_id: [output] pattern id
6699 *
6700 * This function loops through request id to pattern id array
6701 * reset request id to 0 (slot available again) and
6702 * return pattern id
6703 *
6704 * Return: 0 on success and errno on failure
6705 */
6706static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6707 uint32_t request_id,
6708 uint8_t *pattern_id)
6709{
6710 uint32_t i;
6711
6712 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6713 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6714 {
6715 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6716 {
6717 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6718 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6719 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6720 return 0;
6721 }
6722 }
6723 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6724 return -EINVAL;
6725}
6726
6727
6728/*
6729 * define short names for the global vendor params
6730 * used by __wlan_hdd_cfg80211_offloaded_packets()
6731 */
6732#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6733#define PARAM_REQUEST_ID \
6734 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6735#define PARAM_CONTROL \
6736 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6737#define PARAM_IP_PACKET \
6738 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6739#define PARAM_SRC_MAC_ADDR \
6740 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6741#define PARAM_DST_MAC_ADDR \
6742 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6743#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6744
6745/**
6746 * wlan_hdd_add_tx_ptrn() - add tx pattern
6747 * @adapter: adapter pointer
6748 * @hdd_ctx: hdd context
6749 * @tb: nl attributes
6750 *
6751 * This function reads the NL attributes and forms a AddTxPtrn message
6752 * posts it to SME.
6753 *
6754 */
6755static int
6756wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6757 struct nlattr **tb)
6758{
6759 struct sSirAddPeriodicTxPtrn *add_req;
6760 eHalStatus status;
6761 uint32_t request_id, ret, len;
6762 uint8_t pattern_id = 0;
6763 v_MACADDR_t dst_addr;
6764 uint16_t eth_type = htons(ETH_P_IP);
6765
6766 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6767 {
6768 hddLog(LOGE, FL("Not in Connected state!"));
6769 return -ENOTSUPP;
6770 }
6771
6772 add_req = vos_mem_malloc(sizeof(*add_req));
6773 if (!add_req)
6774 {
6775 hddLog(LOGE, FL("memory allocation failed"));
6776 return -ENOMEM;
6777 }
6778
6779 /* Parse and fetch request Id */
6780 if (!tb[PARAM_REQUEST_ID])
6781 {
6782 hddLog(LOGE, FL("attr request id failed"));
6783 goto fail;
6784 }
6785
6786 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6787 hddLog(LOG1, FL("Request Id: %u"), request_id);
6788 if (request_id == 0)
6789 {
6790 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306791 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306792 }
6793
6794 if (!tb[PARAM_PERIOD])
6795 {
6796 hddLog(LOGE, FL("attr period failed"));
6797 goto fail;
6798 }
6799 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6800 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6801 if (add_req->usPtrnIntervalMs == 0)
6802 {
6803 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6804 goto fail;
6805 }
6806
6807 if (!tb[PARAM_SRC_MAC_ADDR])
6808 {
6809 hddLog(LOGE, FL("attr source mac address failed"));
6810 goto fail;
6811 }
6812 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6813 VOS_MAC_ADDR_SIZE);
6814 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6815 MAC_ADDR_ARRAY(add_req->macAddress));
6816
6817 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6818 VOS_MAC_ADDR_SIZE))
6819 {
6820 hddLog(LOGE,
6821 FL("input src mac address and connected ap bssid are different"));
6822 goto fail;
6823 }
6824
6825 if (!tb[PARAM_DST_MAC_ADDR])
6826 {
6827 hddLog(LOGE, FL("attr dst mac address failed"));
6828 goto fail;
6829 }
6830 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6831 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6832 MAC_ADDR_ARRAY(dst_addr.bytes));
6833
6834 if (!tb[PARAM_IP_PACKET])
6835 {
6836 hddLog(LOGE, FL("attr ip packet failed"));
6837 goto fail;
6838 }
6839 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6840 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6841
6842 if (add_req->ucPtrnSize < 0 ||
6843 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6844 HDD_ETH_HEADER_LEN))
6845 {
6846 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6847 add_req->ucPtrnSize);
6848 goto fail;
6849 }
6850
6851 len = 0;
6852 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6853 len += VOS_MAC_ADDR_SIZE;
6854 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6855 VOS_MAC_ADDR_SIZE);
6856 len += VOS_MAC_ADDR_SIZE;
6857 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6858 len += 2;
6859
6860 /*
6861 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6862 * ------------------------------------------------------------
6863 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6864 * ------------------------------------------------------------
6865 */
6866 vos_mem_copy(&add_req->ucPattern[len],
6867 nla_data(tb[PARAM_IP_PACKET]),
6868 add_req->ucPtrnSize);
6869 add_req->ucPtrnSize += len;
6870
6871 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6872 add_req->ucPattern, add_req->ucPtrnSize);
6873
6874 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6875 if (ret)
6876 {
6877 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6878 goto fail;
6879 }
6880 add_req->ucPtrnId = pattern_id;
6881 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6882
6883 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6884 if (!HAL_STATUS_SUCCESS(status))
6885 {
6886 hddLog(LOGE,
6887 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6888 goto fail;
6889 }
6890
6891 EXIT();
6892 vos_mem_free(add_req);
6893 return 0;
6894
6895fail:
6896 vos_mem_free(add_req);
6897 return -EINVAL;
6898}
6899
6900/**
6901 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6902 * @adapter: adapter pointer
6903 * @hdd_ctx: hdd context
6904 * @tb: nl attributes
6905 *
6906 * This function reads the NL attributes and forms a DelTxPtrn message
6907 * posts it to SME.
6908 *
6909 */
6910static int
6911wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6912 struct nlattr **tb)
6913{
6914 struct sSirDelPeriodicTxPtrn *del_req;
6915 eHalStatus status;
6916 uint32_t request_id, ret;
6917 uint8_t pattern_id = 0;
6918
6919 /* Parse and fetch request Id */
6920 if (!tb[PARAM_REQUEST_ID])
6921 {
6922 hddLog(LOGE, FL("attr request id failed"));
6923 return -EINVAL;
6924 }
6925 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6926 if (request_id == 0)
6927 {
6928 hddLog(LOGE, FL("request_id cannot be zero"));
6929 return -EINVAL;
6930 }
6931
6932 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6933 if (ret)
6934 {
6935 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6936 return -EINVAL;
6937 }
6938
6939 del_req = vos_mem_malloc(sizeof(*del_req));
6940 if (!del_req)
6941 {
6942 hddLog(LOGE, FL("memory allocation failed"));
6943 return -ENOMEM;
6944 }
6945
6946 vos_mem_set(del_req, sizeof(*del_req), 0);
6947 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6948 VOS_MAC_ADDR_SIZE);
6949 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6950 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6951 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6952 request_id, pattern_id, del_req->ucPatternIdBitmap);
6953
6954 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6955 if (!HAL_STATUS_SUCCESS(status))
6956 {
6957 hddLog(LOGE,
6958 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6959 goto fail;
6960 }
6961
6962 EXIT();
6963 vos_mem_free(del_req);
6964 return 0;
6965
6966fail:
6967 vos_mem_free(del_req);
6968 return -EINVAL;
6969}
6970
6971
6972/**
6973 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6974 * @wiphy: Pointer to wireless phy
6975 * @wdev: Pointer to wireless device
6976 * @data: Pointer to data
6977 * @data_len: Data length
6978 *
6979 * Return: 0 on success, negative errno on failure
6980 */
6981static int
6982__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6983 struct wireless_dev *wdev,
6984 const void *data,
6985 int data_len)
6986{
6987 struct net_device *dev = wdev->netdev;
6988 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6989 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6990 struct nlattr *tb[PARAM_MAX + 1];
6991 uint8_t control;
6992 int ret;
6993 static const struct nla_policy policy[PARAM_MAX + 1] =
6994 {
6995 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6996 [PARAM_CONTROL] = { .type = NLA_U32 },
6997 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
6998 .len = VOS_MAC_ADDR_SIZE },
6999 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7000 .len = VOS_MAC_ADDR_SIZE },
7001 [PARAM_PERIOD] = { .type = NLA_U32 },
7002 };
7003
7004 ENTER();
7005
7006 ret = wlan_hdd_validate_context(hdd_ctx);
7007 if (0 != ret)
7008 {
7009 hddLog(LOGE, FL("HDD context is not valid"));
7010 return ret;
7011 }
7012
7013 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7014 {
7015 hddLog(LOGE,
7016 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7017 return -ENOTSUPP;
7018 }
7019
7020 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7021 {
7022 hddLog(LOGE, FL("Invalid ATTR"));
7023 return -EINVAL;
7024 }
7025
7026 if (!tb[PARAM_CONTROL])
7027 {
7028 hddLog(LOGE, FL("attr control failed"));
7029 return -EINVAL;
7030 }
7031 control = nla_get_u32(tb[PARAM_CONTROL]);
7032 hddLog(LOG1, FL("Control: %d"), control);
7033
7034 if (control == WLAN_START_OFFLOADED_PACKETS)
7035 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7036 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7037 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7038 else
7039 {
7040 hddLog(LOGE, FL("Invalid control: %d"), control);
7041 return -EINVAL;
7042 }
7043}
7044
7045/*
7046 * done with short names for the global vendor params
7047 * used by __wlan_hdd_cfg80211_offloaded_packets()
7048 */
7049#undef PARAM_MAX
7050#undef PARAM_REQUEST_ID
7051#undef PARAM_CONTROL
7052#undef PARAM_IP_PACKET
7053#undef PARAM_SRC_MAC_ADDR
7054#undef PARAM_DST_MAC_ADDR
7055#undef PARAM_PERIOD
7056
7057/**
7058 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7059 * @wiphy: wiphy structure pointer
7060 * @wdev: Wireless device structure pointer
7061 * @data: Pointer to the data received
7062 * @data_len: Length of @data
7063 *
7064 * Return: 0 on success; errno on failure
7065 */
7066static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7067 struct wireless_dev *wdev,
7068 const void *data,
7069 int data_len)
7070{
7071 int ret = 0;
7072
7073 vos_ssr_protect(__func__);
7074 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7075 wdev, data, data_len);
7076 vos_ssr_unprotect(__func__);
7077
7078 return ret;
7079}
7080#endif
7081
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307082static const struct
7083nla_policy
7084qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7085 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7086};
7087
7088/**
7089 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7090 * get link properties like nss, rate flags and operating frequency for
7091 * the connection with the given peer.
7092 * @wiphy: WIPHY structure pointer
7093 * @wdev: Wireless device structure pointer
7094 * @data: Pointer to the data received
7095 * @data_len: Length of the data received
7096 *
7097 * This function return the above link properties on success.
7098 *
7099 * Return: 0 on success and errno on failure
7100 */
7101static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7102 struct wireless_dev *wdev,
7103 const void *data,
7104 int data_len)
7105{
7106 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7107 struct net_device *dev = wdev->netdev;
7108 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7109 hdd_station_ctx_t *hdd_sta_ctx;
7110 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7111 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7112 uint32_t sta_id;
7113 struct sk_buff *reply_skb;
7114 uint32_t rate_flags = 0;
7115 uint8_t nss;
7116 uint8_t final_rate_flags = 0;
7117 uint32_t freq;
7118 v_CONTEXT_t pVosContext = NULL;
7119 ptSapContext pSapCtx = NULL;
7120
7121 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7122 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7123 return -EINVAL;
7124 }
7125
7126 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7127 qca_wlan_vendor_attr_policy)) {
7128 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7129 return -EINVAL;
7130 }
7131
7132 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7133 hddLog(VOS_TRACE_LEVEL_ERROR,
7134 FL("Attribute peerMac not provided for mode=%d"),
7135 adapter->device_mode);
7136 return -EINVAL;
7137 }
7138
7139 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7140 sizeof(peer_mac));
7141 hddLog(VOS_TRACE_LEVEL_INFO,
7142 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7143 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7144
7145 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7146 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7147 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7148 if ((hdd_sta_ctx->conn_info.connState !=
7149 eConnectionState_Associated) ||
7150 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7151 VOS_MAC_ADDRESS_LEN)) {
7152 hddLog(VOS_TRACE_LEVEL_ERROR,
7153 FL("Not Associated to mac "MAC_ADDRESS_STR),
7154 MAC_ADDR_ARRAY(peer_mac));
7155 return -EINVAL;
7156 }
7157
7158 nss = 1; //pronto supports only one spatial stream
7159 freq = vos_chan_to_freq(
7160 hdd_sta_ctx->conn_info.operationChannel);
7161 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7162
7163 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7164 adapter->device_mode == WLAN_HDD_SOFTAP) {
7165
7166 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7167 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7168 if(pSapCtx == NULL){
7169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7170 FL("psapCtx is NULL"));
7171 return -ENOENT;
7172 }
7173
7174
7175 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7176 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7177 !vos_is_macaddr_broadcast(
7178 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7179 vos_mem_compare(
7180 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7181 peer_mac, VOS_MAC_ADDRESS_LEN))
7182 break;
7183 }
7184
7185 if (WLAN_MAX_STA_COUNT == sta_id) {
7186 hddLog(VOS_TRACE_LEVEL_ERROR,
7187 FL("No active peer with mac="MAC_ADDRESS_STR),
7188 MAC_ADDR_ARRAY(peer_mac));
7189 return -EINVAL;
7190 }
7191
7192 nss = 1; //pronto supports only one spatial stream
7193 freq = vos_chan_to_freq(
7194 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7195 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7196 } else {
7197 hddLog(VOS_TRACE_LEVEL_ERROR,
7198 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7199 MAC_ADDR_ARRAY(peer_mac));
7200 return -EINVAL;
7201 }
7202
7203 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7204 if (rate_flags & eHAL_TX_RATE_VHT80) {
7205 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7206 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7207 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7208 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7209 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7210 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7211 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7212 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7213 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7214 if (rate_flags & eHAL_TX_RATE_HT40)
7215 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7216 }
7217
7218 if (rate_flags & eHAL_TX_RATE_SGI) {
7219 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7220 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7221 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7222 }
7223 }
7224
7225 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7226 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7227
7228 if (NULL == reply_skb) {
7229 hddLog(VOS_TRACE_LEVEL_ERROR,
7230 FL("getLinkProperties: skb alloc failed"));
7231 return -EINVAL;
7232 }
7233
7234 if (nla_put_u8(reply_skb,
7235 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7236 nss) ||
7237 nla_put_u8(reply_skb,
7238 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7239 final_rate_flags) ||
7240 nla_put_u32(reply_skb,
7241 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7242 freq)) {
7243 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7244 kfree_skb(reply_skb);
7245 return -EINVAL;
7246 }
7247
7248 return cfg80211_vendor_cmd_reply(reply_skb);
7249}
7250
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307251#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7252#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7253#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7254#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307255#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7256 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307257
7258/**
7259 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7260 * vendor command
7261 *
7262 * @wiphy: wiphy device pointer
7263 * @wdev: wireless device pointer
7264 * @data: Vendor command data buffer
7265 * @data_len: Buffer length
7266 *
7267 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7268 *
7269 * Return: EOK or other error codes.
7270 */
7271
7272static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7273 struct wireless_dev *wdev,
7274 const void *data,
7275 int data_len)
7276{
7277 struct net_device *dev = wdev->netdev;
7278 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7279 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7280 hdd_station_ctx_t *pHddStaCtx;
7281 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7282 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307283 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307284 eHalStatus status;
7285 int ret_val;
7286 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7287 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7288 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307289 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7290 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7291 { .type = NLA_U32},
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307292 };
7293
7294 ENTER();
7295
7296 if (VOS_FTM_MODE == hdd_get_conparam()) {
7297 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7298 return -EINVAL;
7299 }
7300
7301 ret_val = wlan_hdd_validate_context(pHddCtx);
7302 if (ret_val) {
7303 return ret_val;
7304 }
7305
7306 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7307
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307308 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7309 hddLog(LOGE, FL("Invalid ATTR"));
7310 return -EINVAL;
7311 }
7312
7313 /* check the Wifi Capability */
7314 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7315 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7316 {
7317 hddLog(VOS_TRACE_LEVEL_ERROR,
7318 FL("WIFICONFIG not supported by Firmware"));
7319 return -EINVAL;
7320 }
7321
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307322 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7323 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7324 modifyRoamParamsReq.value =
7325 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7326
7327 if (eHAL_STATUS_SUCCESS !=
7328 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7329 {
7330 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7331 ret_val = -EINVAL;
7332 }
7333 return ret_val;
7334 }
7335
7336 /* Moved this down in order to provide provision to set beacon
7337 * miss penalty count irrespective of connection state.
7338 */
7339 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7340 hddLog(LOGE, FL("Not in Connected state!"));
7341 return -ENOTSUPP;
7342 }
7343
7344 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307345
7346 if (!pReq) {
7347 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7348 "%s: Not able to allocate memory for tSetWifiConfigParams",
7349 __func__);
7350 return eHAL_STATUS_E_MALLOC_FAILED;
7351 }
7352
7353 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7354
7355 pReq->sessionId = pAdapter->sessionId;
7356 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7357
7358 if (tb[PARAM_MODULATED_DTIM]) {
7359 pReq->paramValue = nla_get_u32(
7360 tb[PARAM_MODULATED_DTIM]);
7361 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7362 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307363 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307364 hdd_set_pwrparams(pHddCtx);
7365 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7366 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7367
7368 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7369 iw_full_power_cbfn, pAdapter,
7370 eSME_FULL_PWR_NEEDED_BY_HDD);
7371 }
7372 else
7373 {
7374 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7375 }
7376 }
7377
7378 if (tb[PARAM_STATS_AVG_FACTOR]) {
7379 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7380 pReq->paramValue = nla_get_u16(
7381 tb[PARAM_STATS_AVG_FACTOR]);
7382 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7383 pReq->paramType, pReq->paramValue);
7384 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7385
7386 if (eHAL_STATUS_SUCCESS != status)
7387 {
7388 vos_mem_free(pReq);
7389 pReq = NULL;
7390 ret_val = -EPERM;
7391 return ret_val;
7392 }
7393 }
7394
7395
7396 if (tb[PARAM_GUARD_TIME]) {
7397 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7398 pReq->paramValue = nla_get_u32(
7399 tb[PARAM_GUARD_TIME]);
7400 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7401 pReq->paramType, pReq->paramValue);
7402 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7403
7404 if (eHAL_STATUS_SUCCESS != status)
7405 {
7406 vos_mem_free(pReq);
7407 pReq = NULL;
7408 ret_val = -EPERM;
7409 return ret_val;
7410 }
7411
7412 }
7413
7414 EXIT();
7415 return ret_val;
7416}
7417
7418/**
7419 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7420 * vendor command
7421 *
7422 * @wiphy: wiphy device pointer
7423 * @wdev: wireless device pointer
7424 * @data: Vendor command data buffer
7425 * @data_len: Buffer length
7426 *
7427 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7428 *
7429 * Return: EOK or other error codes.
7430 */
7431static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7432 struct wireless_dev *wdev,
7433 const void *data,
7434 int data_len)
7435{
7436 int ret;
7437
7438 vos_ssr_protect(__func__);
7439 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7440 data, data_len);
7441 vos_ssr_unprotect(__func__);
7442
7443 return ret;
7444}
Sunil Duttc69bccb2014-05-26 21:30:20 +05307445const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7446{
Mukul Sharma2a271632014-10-13 14:59:01 +05307447 {
7448 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7449 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7450 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7451 WIPHY_VENDOR_CMD_NEED_NETDEV |
7452 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307453 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307454 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307455
7456 {
7457 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7458 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7459 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7460 WIPHY_VENDOR_CMD_NEED_NETDEV |
7461 WIPHY_VENDOR_CMD_NEED_RUNNING,
7462 .doit = wlan_hdd_cfg80211_nan_request
7463 },
7464
Sunil Duttc69bccb2014-05-26 21:30:20 +05307465#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7466 {
7467 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7468 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7469 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7470 WIPHY_VENDOR_CMD_NEED_NETDEV |
7471 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307472 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307473 },
7474
7475 {
7476 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7477 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7478 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7479 WIPHY_VENDOR_CMD_NEED_NETDEV |
7480 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307481 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307482 },
7483
7484 {
7485 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7486 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
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_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307491 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307492#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307493#ifdef WLAN_FEATURE_EXTSCAN
7494 {
7495 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7496 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7497 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7498 WIPHY_VENDOR_CMD_NEED_NETDEV |
7499 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307500 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307501 },
7502 {
7503 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7504 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7505 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7506 WIPHY_VENDOR_CMD_NEED_NETDEV |
7507 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307508 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307509 },
7510 {
7511 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7512 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7513 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7514 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307515 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307516 },
7517 {
7518 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7519 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7520 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7521 WIPHY_VENDOR_CMD_NEED_NETDEV |
7522 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307523 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307524 },
7525 {
7526 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7527 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7528 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7529 WIPHY_VENDOR_CMD_NEED_NETDEV |
7530 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307531 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307532 },
7533 {
7534 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7535 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7536 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7537 WIPHY_VENDOR_CMD_NEED_NETDEV |
7538 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307539 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307540 },
7541 {
7542 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7543 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7544 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7545 WIPHY_VENDOR_CMD_NEED_NETDEV |
7546 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307547 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307548 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307549 {
7550 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7551 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7552 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7553 WIPHY_VENDOR_CMD_NEED_NETDEV |
7554 WIPHY_VENDOR_CMD_NEED_RUNNING,
7555 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7556 },
7557 {
7558 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7559 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7560 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7561 WIPHY_VENDOR_CMD_NEED_NETDEV |
7562 WIPHY_VENDOR_CMD_NEED_RUNNING,
7563 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7564 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307565#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307566/*EXT TDLS*/
7567 {
7568 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7569 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7570 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7571 WIPHY_VENDOR_CMD_NEED_NETDEV |
7572 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307573 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307574 },
7575 {
7576 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7577 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7578 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7579 WIPHY_VENDOR_CMD_NEED_NETDEV |
7580 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307581 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307582 },
7583 {
7584 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7585 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7586 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7587 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307588 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307589 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307590 {
7591 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7592 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7593 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7594 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307595 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307596 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307597 {
7598 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7599 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7600 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7601 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307602 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307603 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307604 {
7605 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7606 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7607 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7608 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307609 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307610 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307611 {
7612 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7613 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7614 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7615 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307616 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307617 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307618 {
7619 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307620 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7621 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7622 WIPHY_VENDOR_CMD_NEED_NETDEV |
7623 WIPHY_VENDOR_CMD_NEED_RUNNING,
7624 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7625 },
7626 {
7627 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307628 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7629 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7630 WIPHY_VENDOR_CMD_NEED_NETDEV |
7631 WIPHY_VENDOR_CMD_NEED_RUNNING,
7632 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307633 },
7634 {
7635 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7636 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7637 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7638 WIPHY_VENDOR_CMD_NEED_NETDEV,
7639 .doit = wlan_hdd_cfg80211_wifi_logger_start
7640 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307641 {
7642 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7643 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7644 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7645 WIPHY_VENDOR_CMD_NEED_NETDEV|
7646 WIPHY_VENDOR_CMD_NEED_RUNNING,
7647 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307648 },
7649 {
7650 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7651 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7652 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7653 WIPHY_VENDOR_CMD_NEED_NETDEV |
7654 WIPHY_VENDOR_CMD_NEED_RUNNING,
7655 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307656 },
7657 {
7658 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7659 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7660 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7661 WIPHY_VENDOR_CMD_NEED_NETDEV |
7662 WIPHY_VENDOR_CMD_NEED_RUNNING,
7663 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307664 },
7665#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7666 {
7667 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7668 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7669 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7670 WIPHY_VENDOR_CMD_NEED_NETDEV |
7671 WIPHY_VENDOR_CMD_NEED_RUNNING,
7672 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307673 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307674#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307675 {
7676 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7677 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7678 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7679 WIPHY_VENDOR_CMD_NEED_NETDEV |
7680 WIPHY_VENDOR_CMD_NEED_RUNNING,
7681 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307682 },
7683 {
7684 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7685 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7686 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7687 WIPHY_VENDOR_CMD_NEED_NETDEV |
7688 WIPHY_VENDOR_CMD_NEED_RUNNING,
7689 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307690 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05307691};
7692
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007693/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307694static const
7695struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007696{
7697#ifdef FEATURE_WLAN_CH_AVOID
7698 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307699 .vendor_id = QCA_NL80211_VENDOR_ID,
7700 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007701 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307702#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7703#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7704 {
7705 /* Index = 1*/
7706 .vendor_id = QCA_NL80211_VENDOR_ID,
7707 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7708 },
7709 {
7710 /* Index = 2*/
7711 .vendor_id = QCA_NL80211_VENDOR_ID,
7712 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7713 },
7714 {
7715 /* Index = 3*/
7716 .vendor_id = QCA_NL80211_VENDOR_ID,
7717 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7718 },
7719 {
7720 /* Index = 4*/
7721 .vendor_id = QCA_NL80211_VENDOR_ID,
7722 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7723 },
7724 {
7725 /* Index = 5*/
7726 .vendor_id = QCA_NL80211_VENDOR_ID,
7727 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7728 },
7729 {
7730 /* Index = 6*/
7731 .vendor_id = QCA_NL80211_VENDOR_ID,
7732 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7733 },
7734#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307735#ifdef WLAN_FEATURE_EXTSCAN
7736 {
7737 .vendor_id = QCA_NL80211_VENDOR_ID,
7738 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7739 },
7740 {
7741 .vendor_id = QCA_NL80211_VENDOR_ID,
7742 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7743 },
7744 {
7745 .vendor_id = QCA_NL80211_VENDOR_ID,
7746 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7747 },
7748 {
7749 .vendor_id = QCA_NL80211_VENDOR_ID,
7750 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7751 },
7752 {
7753 .vendor_id = QCA_NL80211_VENDOR_ID,
7754 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7755 },
7756 {
7757 .vendor_id = QCA_NL80211_VENDOR_ID,
7758 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7759 },
7760 {
7761 .vendor_id = QCA_NL80211_VENDOR_ID,
7762 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7763 },
7764 {
7765 .vendor_id = QCA_NL80211_VENDOR_ID,
7766 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7767 },
7768 {
7769 .vendor_id = QCA_NL80211_VENDOR_ID,
7770 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7771 },
7772 {
7773 .vendor_id = QCA_NL80211_VENDOR_ID,
7774 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7775 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307776 {
7777 .vendor_id = QCA_NL80211_VENDOR_ID,
7778 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7779 },
7780 {
7781 .vendor_id = QCA_NL80211_VENDOR_ID,
7782 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7783 },
7784 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7785 .vendor_id = QCA_NL80211_VENDOR_ID,
7786 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7787 },
7788 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7789 .vendor_id = QCA_NL80211_VENDOR_ID,
7790 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7791 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307792#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307793/*EXT TDLS*/
7794 {
7795 .vendor_id = QCA_NL80211_VENDOR_ID,
7796 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7797 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307798 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7799 .vendor_id = QCA_NL80211_VENDOR_ID,
7800 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7801 },
7802
Srinivas Dasari030bad32015-02-18 23:23:54 +05307803
7804 {
7805 .vendor_id = QCA_NL80211_VENDOR_ID,
7806 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7807 },
7808
Sushant Kaushik084f6592015-09-10 13:11:56 +05307809 {
7810 .vendor_id = QCA_NL80211_VENDOR_ID,
7811 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307812 },
7813 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7814 .vendor_id = QCA_NL80211_VENDOR_ID,
7815 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7816 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05307817 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
7818 .vendor_id = QCA_NL80211_VENDOR_ID,
7819 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
7820 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307821
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007822};
7823
Jeff Johnson295189b2012-06-20 16:38:30 -07007824/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307825 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307826 * This function is called by hdd_wlan_startup()
7827 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307828 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007829 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307830struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007831{
7832 struct wiphy *wiphy;
7833 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307834 /*
7835 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007836 */
7837 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7838
7839 if (!wiphy)
7840 {
7841 /* Print error and jump into err label and free the memory */
7842 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7843 return NULL;
7844 }
7845
Sunil Duttc69bccb2014-05-26 21:30:20 +05307846
Jeff Johnson295189b2012-06-20 16:38:30 -07007847 return wiphy;
7848}
7849
7850/*
7851 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307852 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007853 * private ioctl to change the band value
7854 */
7855int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7856{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307857 int i, j;
7858 eNVChannelEnabledType channelEnabledState;
7859
Jeff Johnsone7245742012-09-05 17:12:55 -07007860 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307861
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307862 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007863 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307864
7865 if (NULL == wiphy->bands[i])
7866 {
7867 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7868 __func__, i);
7869 continue;
7870 }
7871
7872 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7873 {
7874 struct ieee80211_supported_band *band = wiphy->bands[i];
7875
7876 channelEnabledState = vos_nv_getChannelEnabledState(
7877 band->channels[j].hw_value);
7878
7879 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7880 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307881 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307882 continue;
7883 }
7884 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7885 {
7886 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7887 continue;
7888 }
7889
7890 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7891 NV_CHANNEL_INVALID == channelEnabledState)
7892 {
7893 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7894 }
7895 else if (NV_CHANNEL_DFS == channelEnabledState)
7896 {
7897 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7898 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7899 }
7900 else
7901 {
7902 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7903 |IEEE80211_CHAN_RADAR);
7904 }
7905 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007906 }
7907 return 0;
7908}
7909/*
7910 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307911 * This function is called by hdd_wlan_startup()
7912 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007913 * This function is used to initialize and register wiphy structure.
7914 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307915int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007916 struct wiphy *wiphy,
7917 hdd_config_t *pCfg
7918 )
7919{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307920 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307921 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7922
Jeff Johnsone7245742012-09-05 17:12:55 -07007923 ENTER();
7924
Jeff Johnson295189b2012-06-20 16:38:30 -07007925 /* Now bind the underlying wlan device with wiphy */
7926 set_wiphy_dev(wiphy, dev);
7927
7928 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007929
Kiet Lam6c583332013-10-14 05:37:09 +05307930#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007931 /* the flag for the other case would be initialzed in
7932 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05307933#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7934 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
7935#else
Amar Singhal0a402232013-10-11 20:57:16 -07007936 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307937#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05307938#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007939
Amar Singhalfddc28c2013-09-05 13:03:40 -07007940 /* This will disable updating of NL channels from passive to
7941 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307942#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7943 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7944#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007945 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307946#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007947
Amar Singhala49cbc52013-10-08 18:37:44 -07007948
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007949#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007950 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7951 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7952 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007953 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307954#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05307955 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307956#else
7957 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7958#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007959#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007960
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007961#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007962 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007963#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007964 || pCfg->isFastRoamIniFeatureEnabled
7965#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007966#ifdef FEATURE_WLAN_ESE
7967 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007968#endif
7969 )
7970 {
7971 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7972 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007973#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007974#ifdef FEATURE_WLAN_TDLS
7975 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7976 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7977#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307978#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307979 if (pCfg->configPNOScanSupport)
7980 {
7981 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7982 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7983 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7984 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7985 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307986#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007987
Abhishek Singh10d85972015-04-17 10:27:23 +05307988#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7989 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7990#endif
7991
Amar Singhalfddc28c2013-09-05 13:03:40 -07007992#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007993 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
7994 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07007995 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007996 driver need to determine what to do with both
7997 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07007998
7999 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008000#else
8001 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008002#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008003
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308004 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8005
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308006 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008007
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308008 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8009
Jeff Johnson295189b2012-06-20 16:38:30 -07008010 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308011 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8012 | BIT(NL80211_IFTYPE_ADHOC)
8013 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8014 | BIT(NL80211_IFTYPE_P2P_GO)
8015 | BIT(NL80211_IFTYPE_AP);
8016
8017 if (VOS_MONITOR_MODE == hdd_get_conparam())
8018 {
8019 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8020 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008021
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308022 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008023 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308024#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8025 if( pCfg->enableMCC )
8026 {
8027 /* Currently, supports up to two channels */
8028 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008029
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308030 if( !pCfg->allowMCCGODiffBI )
8031 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008032
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308033 }
8034 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8035 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008036#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308037 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008038
Jeff Johnson295189b2012-06-20 16:38:30 -07008039 /* Before registering we need to update the ht capabilitied based
8040 * on ini values*/
8041 if( !pCfg->ShortGI20MhzEnable )
8042 {
8043 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8044 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008045 }
8046
8047 if( !pCfg->ShortGI40MhzEnable )
8048 {
8049 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8050 }
8051
8052 if( !pCfg->nChannelBondingMode5GHz )
8053 {
8054 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8055 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308056 /*
8057 * In case of static linked driver at the time of driver unload,
8058 * module exit doesn't happens. Module cleanup helps in cleaning
8059 * of static memory.
8060 * If driver load happens statically, at the time of driver unload,
8061 * wiphy flags don't get reset because of static memory.
8062 * It's better not to store channel in static memory.
8063 */
8064 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8065 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8066 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8067 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8068 {
8069 hddLog(VOS_TRACE_LEVEL_ERROR,
8070 FL("Not enough memory to allocate channels"));
8071 return -ENOMEM;
8072 }
8073 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8074 &hdd_channels_2_4_GHZ[0],
8075 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008076
Agrawal Ashish97dec502015-11-26 20:20:58 +05308077 if (true == hdd_is_5g_supported(pHddCtx))
8078 {
8079 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8080 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8081 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8082 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8083 {
8084 hddLog(VOS_TRACE_LEVEL_ERROR,
8085 FL("Not enough memory to allocate channels"));
8086 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8087 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8088 return -ENOMEM;
8089 }
8090 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8091 &hdd_channels_5_GHZ[0],
8092 sizeof(hdd_channels_5_GHZ));
8093 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308094
8095 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8096 {
8097
8098 if (NULL == wiphy->bands[i])
8099 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308100 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308101 __func__, i);
8102 continue;
8103 }
8104
8105 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8106 {
8107 struct ieee80211_supported_band *band = wiphy->bands[i];
8108
8109 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8110 {
8111 // Enable social channels for P2P
8112 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8113 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8114 else
8115 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8116 continue;
8117 }
8118 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8119 {
8120 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8121 continue;
8122 }
8123 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008124 }
8125 /*Initialise the supported cipher suite details*/
8126 wiphy->cipher_suites = hdd_cipher_suites;
8127 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8128
8129 /*signal strength in mBm (100*dBm) */
8130 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8131
8132#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308133 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008134#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008135
Sunil Duttc69bccb2014-05-26 21:30:20 +05308136 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8137 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008138 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8139 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8140
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308141 EXIT();
8142 return 0;
8143}
8144
8145/* In this function we are registering wiphy. */
8146int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8147{
8148 ENTER();
8149 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008150 if (0 > wiphy_register(wiphy))
8151 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308152 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008153 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8154 return -EIO;
8155 }
8156
8157 EXIT();
8158 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308159}
Jeff Johnson295189b2012-06-20 16:38:30 -07008160
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308161/* In this function we are updating channel list when,
8162 regulatory domain is FCC and country code is US.
8163 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8164 As per FCC smart phone is not a indoor device.
8165 GO should not opeate on indoor channels */
8166void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8167{
8168 int j;
8169 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8170 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8171 //Default counrtycode from NV at the time of wiphy initialization.
8172 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8173 &defaultCountryCode[0]))
8174 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008175 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308176 }
8177 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8178 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308179 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8180 {
8181 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8182 return;
8183 }
8184 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8185 {
8186 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8187 // Mark UNII -1 band channel as passive
8188 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8189 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8190 }
8191 }
8192}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308193/* This function registers for all frame which supplicant is interested in */
8194void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008195{
Jeff Johnson295189b2012-06-20 16:38:30 -07008196 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8197 /* Register for all P2P action, public action etc frames */
8198 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008199 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308200 /* Register frame indication call back */
8201 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008202 /* Right now we are registering these frame when driver is getting
8203 initialized. Once we will move to 2.6.37 kernel, in which we have
8204 frame register ops, we will move this code as a part of that */
8205 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308206 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008207 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8208
8209 /* GAS Initial Response */
8210 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8211 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308212
Jeff Johnson295189b2012-06-20 16:38:30 -07008213 /* GAS Comeback Request */
8214 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8215 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8216
8217 /* GAS Comeback Response */
8218 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8219 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8220
8221 /* P2P Public Action */
8222 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308223 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 P2P_PUBLIC_ACTION_FRAME_SIZE );
8225
8226 /* P2P Action */
8227 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8228 (v_U8_t*)P2P_ACTION_FRAME,
8229 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008230
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308231 /* WNM BSS Transition Request frame */
8232 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8233 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8234 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008235
8236 /* WNM-Notification */
8237 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8238 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8239 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008240}
8241
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308242void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008243{
Jeff Johnson295189b2012-06-20 16:38:30 -07008244 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8245 /* Register for all P2P action, public action etc frames */
8246 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8247
Jeff Johnsone7245742012-09-05 17:12:55 -07008248 ENTER();
8249
Jeff Johnson295189b2012-06-20 16:38:30 -07008250 /* Right now we are registering these frame when driver is getting
8251 initialized. Once we will move to 2.6.37 kernel, in which we have
8252 frame register ops, we will move this code as a part of that */
8253 /* GAS Initial Request */
8254
8255 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8256 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8257
8258 /* GAS Initial Response */
8259 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8260 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308261
Jeff Johnson295189b2012-06-20 16:38:30 -07008262 /* GAS Comeback Request */
8263 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8264 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8265
8266 /* GAS Comeback Response */
8267 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8268 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8269
8270 /* P2P Public Action */
8271 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308272 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008273 P2P_PUBLIC_ACTION_FRAME_SIZE );
8274
8275 /* P2P Action */
8276 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8277 (v_U8_t*)P2P_ACTION_FRAME,
8278 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008279 /* WNM-Notification */
8280 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8281 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8282 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008283}
8284
8285#ifdef FEATURE_WLAN_WAPI
8286void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308287 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008288{
8289 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8290 tCsrRoamSetKey setKey;
8291 v_BOOL_t isConnected = TRUE;
8292 int status = 0;
8293 v_U32_t roamId= 0xFF;
8294 tANI_U8 *pKeyPtr = NULL;
8295 int n = 0;
8296
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308297 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8298 __func__, hdd_device_modetoString(pAdapter->device_mode),
8299 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008300
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308301 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008302 setKey.keyId = key_index; // Store Key ID
8303 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8304 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8305 setKey.paeRole = 0 ; // the PAE role
8306 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8307 {
8308 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8309 }
8310 else
8311 {
8312 isConnected = hdd_connIsConnected(pHddStaCtx);
8313 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8314 }
8315 setKey.keyLength = key_Len;
8316 pKeyPtr = setKey.Key;
8317 memcpy( pKeyPtr, key, key_Len);
8318
Arif Hussain6d2a3322013-11-17 19:50:10 -08008319 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008320 __func__, key_Len);
8321 for (n = 0 ; n < key_Len; n++)
8322 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8323 __func__,n,setKey.Key[n]);
8324
8325 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8326 if ( isConnected )
8327 {
8328 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8329 pAdapter->sessionId, &setKey, &roamId );
8330 }
8331 if ( status != 0 )
8332 {
8333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8334 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8335 __LINE__, status );
8336 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8337 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308338 /* Need to clear any trace of key value in the memory.
8339 * Thus zero out the memory even though it is local
8340 * variable.
8341 */
8342 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008343}
8344#endif /* FEATURE_WLAN_WAPI*/
8345
8346#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308347int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008348 beacon_data_t **ppBeacon,
8349 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008350#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308351int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008352 beacon_data_t **ppBeacon,
8353 struct cfg80211_beacon_data *params,
8354 int dtim_period)
8355#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308356{
Jeff Johnson295189b2012-06-20 16:38:30 -07008357 int size;
8358 beacon_data_t *beacon = NULL;
8359 beacon_data_t *old = NULL;
8360 int head_len,tail_len;
8361
Jeff Johnsone7245742012-09-05 17:12:55 -07008362 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008363 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308364 {
8365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8366 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008367 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308368 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008369
8370 old = pAdapter->sessionCtx.ap.beacon;
8371
8372 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308373 {
8374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8375 FL("session(%d) old and new heads points to NULL"),
8376 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008377 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308378 }
8379
8380 if (params->tail && !params->tail_len)
8381 {
8382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8383 FL("tail_len is zero but tail is not NULL"));
8384 return -EINVAL;
8385 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008386
Jeff Johnson295189b2012-06-20 16:38:30 -07008387#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8388 /* Kernel 3.0 is not updating dtim_period for set beacon */
8389 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308390 {
8391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8392 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008393 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308394 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008395#endif
8396
8397 if(params->head)
8398 head_len = params->head_len;
8399 else
8400 head_len = old->head_len;
8401
8402 if(params->tail || !old)
8403 tail_len = params->tail_len;
8404 else
8405 tail_len = old->tail_len;
8406
8407 size = sizeof(beacon_data_t) + head_len + tail_len;
8408
8409 beacon = kzalloc(size, GFP_KERNEL);
8410
8411 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308412 {
8413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8414 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008415 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308416 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008417
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008418#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008419 if(params->dtim_period || !old )
8420 beacon->dtim_period = params->dtim_period;
8421 else
8422 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008423#else
8424 if(dtim_period || !old )
8425 beacon->dtim_period = dtim_period;
8426 else
8427 beacon->dtim_period = old->dtim_period;
8428#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308429
Jeff Johnson295189b2012-06-20 16:38:30 -07008430 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8431 beacon->tail = beacon->head + head_len;
8432 beacon->head_len = head_len;
8433 beacon->tail_len = tail_len;
8434
8435 if(params->head) {
8436 memcpy (beacon->head,params->head,beacon->head_len);
8437 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308438 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07008439 if(old)
8440 memcpy (beacon->head,old->head,beacon->head_len);
8441 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308442
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 if(params->tail) {
8444 memcpy (beacon->tail,params->tail,beacon->tail_len);
8445 }
8446 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308447 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07008448 memcpy (beacon->tail,old->tail,beacon->tail_len);
8449 }
8450
8451 *ppBeacon = beacon;
8452
8453 kfree(old);
8454
8455 return 0;
8456
8457}
Jeff Johnson295189b2012-06-20 16:38:30 -07008458
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308459v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8460#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8461 const v_U8_t *pIes,
8462#else
8463 v_U8_t *pIes,
8464#endif
8465 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008466{
8467 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308468 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008469 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308470
Jeff Johnson295189b2012-06-20 16:38:30 -07008471 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308472 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008473 elem_id = ptr[0];
8474 elem_len = ptr[1];
8475 left -= 2;
8476 if(elem_len > left)
8477 {
8478 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008479 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 eid,elem_len,left);
8481 return NULL;
8482 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308483 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008484 {
8485 return ptr;
8486 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308487
Jeff Johnson295189b2012-06-20 16:38:30 -07008488 left -= elem_len;
8489 ptr += (elem_len + 2);
8490 }
8491 return NULL;
8492}
8493
Jeff Johnson295189b2012-06-20 16:38:30 -07008494/* Check if rate is 11g rate or not */
8495static int wlan_hdd_rate_is_11g(u8 rate)
8496{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008497 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008498 u8 i;
8499 for (i = 0; i < 8; i++)
8500 {
8501 if(rate == gRateArray[i])
8502 return TRUE;
8503 }
8504 return FALSE;
8505}
8506
8507/* Check for 11g rate and set proper 11g only mode */
8508static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8509 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8510{
8511 u8 i, num_rates = pIe[0];
8512
8513 pIe += 1;
8514 for ( i = 0; i < num_rates; i++)
8515 {
8516 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8517 {
8518 /* If rate set have 11g rate than change the mode to 11G */
8519 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8520 if (pIe[i] & BASIC_RATE_MASK)
8521 {
8522 /* If we have 11g rate as basic rate, it means mode
8523 is 11g only mode.
8524 */
8525 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8526 *pCheckRatesfor11g = FALSE;
8527 }
8528 }
8529 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8530 {
8531 *require_ht = TRUE;
8532 }
8533 }
8534 return;
8535}
8536
8537static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8538{
8539 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8540 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8541 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8542 u8 checkRatesfor11g = TRUE;
8543 u8 require_ht = FALSE;
8544 u8 *pIe=NULL;
8545
8546 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8547
8548 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8549 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8550 if (pIe != NULL)
8551 {
8552 pIe += 1;
8553 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8554 &pConfig->SapHw_mode);
8555 }
8556
8557 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8558 WLAN_EID_EXT_SUPP_RATES);
8559 if (pIe != NULL)
8560 {
8561
8562 pIe += 1;
8563 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8564 &pConfig->SapHw_mode);
8565 }
8566
8567 if( pConfig->channel > 14 )
8568 {
8569 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8570 }
8571
8572 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8573 WLAN_EID_HT_CAPABILITY);
8574
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308575 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008576 {
8577 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8578 if(require_ht)
8579 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8580 }
8581}
8582
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308583static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8584 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8585{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008586 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308587 v_U8_t *pIe = NULL;
8588 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8589
8590 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8591 pBeacon->tail, pBeacon->tail_len);
8592
8593 if (pIe)
8594 {
8595 ielen = pIe[1] + 2;
8596 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8597 {
8598 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8599 }
8600 else
8601 {
8602 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8603 return -EINVAL;
8604 }
8605 *total_ielen += ielen;
8606 }
8607 return 0;
8608}
8609
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008610static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8611 v_U8_t *genie, v_U8_t *total_ielen)
8612{
8613 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8614 int left = pBeacon->tail_len;
8615 v_U8_t *ptr = pBeacon->tail;
8616 v_U8_t elem_id, elem_len;
8617 v_U16_t ielen = 0;
8618
8619 if ( NULL == ptr || 0 == left )
8620 return;
8621
8622 while (left >= 2)
8623 {
8624 elem_id = ptr[0];
8625 elem_len = ptr[1];
8626 left -= 2;
8627 if (elem_len > left)
8628 {
8629 hddLog( VOS_TRACE_LEVEL_ERROR,
8630 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8631 elem_id, elem_len, left);
8632 return;
8633 }
8634 if (IE_EID_VENDOR == elem_id)
8635 {
8636 /* skipping the VSIE's which we don't want to include or
8637 * it will be included by existing code
8638 */
8639 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8640#ifdef WLAN_FEATURE_WFD
8641 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8642#endif
8643 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8644 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8645 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8646 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8647 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8648 {
8649 ielen = ptr[1] + 2;
8650 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8651 {
8652 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8653 *total_ielen += ielen;
8654 }
8655 else
8656 {
8657 hddLog( VOS_TRACE_LEVEL_ERROR,
8658 "IE Length is too big "
8659 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8660 elem_id, elem_len, *total_ielen);
8661 }
8662 }
8663 }
8664
8665 left -= elem_len;
8666 ptr += (elem_len + 2);
8667 }
8668 return;
8669}
8670
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008671#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008672static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8673 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008674#else
8675static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8676 struct cfg80211_beacon_data *params)
8677#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008678{
8679 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308680 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008681 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008682 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008683
8684 genie = vos_mem_malloc(MAX_GENIE_LEN);
8685
8686 if(genie == NULL) {
8687
8688 return -ENOMEM;
8689 }
8690
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308691 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8692 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008693 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308694 hddLog(LOGE,
8695 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308696 ret = -EINVAL;
8697 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008698 }
8699
8700#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308701 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8702 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8703 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308704 hddLog(LOGE,
8705 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308706 ret = -EINVAL;
8707 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008708 }
8709#endif
8710
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308711 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8712 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008713 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308714 hddLog(LOGE,
8715 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308716 ret = -EINVAL;
8717 goto done;
8718 }
8719
8720 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8721 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008722 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008723 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008724
8725 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8726 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8727 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8728 {
8729 hddLog(LOGE,
8730 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008731 ret = -EINVAL;
8732 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008733 }
8734
8735 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8736 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8737 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8738 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8739 ==eHAL_STATUS_FAILURE)
8740 {
8741 hddLog(LOGE,
8742 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008743 ret = -EINVAL;
8744 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008745 }
8746
8747 // Added for ProResp IE
8748 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
8749 {
8750 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
8751 u8 probe_rsp_ie_len[3] = {0};
8752 u8 counter = 0;
8753 /* Check Probe Resp Length if it is greater then 255 then Store
8754 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8755 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8756 Store More then 255 bytes into One Variable.
8757 */
8758 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8759 {
8760 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8761 {
8762 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8763 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8764 }
8765 else
8766 {
8767 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8768 rem_probe_resp_ie_len = 0;
8769 }
8770 }
8771
8772 rem_probe_resp_ie_len = 0;
8773
8774 if (probe_rsp_ie_len[0] > 0)
8775 {
8776 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8777 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
8778 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8779 probe_rsp_ie_len[0], NULL,
8780 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8781 {
8782 hddLog(LOGE,
8783 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008784 ret = -EINVAL;
8785 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 }
8787 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8788 }
8789
8790 if (probe_rsp_ie_len[1] > 0)
8791 {
8792 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8793 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
8794 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8795 probe_rsp_ie_len[1], NULL,
8796 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8797 {
8798 hddLog(LOGE,
8799 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008800 ret = -EINVAL;
8801 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008802 }
8803 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8804 }
8805
8806 if (probe_rsp_ie_len[2] > 0)
8807 {
8808 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8809 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
8810 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8811 probe_rsp_ie_len[2], NULL,
8812 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8813 {
8814 hddLog(LOGE,
8815 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008816 ret = -EINVAL;
8817 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008818 }
8819 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8820 }
8821
8822 if (probe_rsp_ie_len[1] == 0 )
8823 {
8824 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8825 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8826 eANI_BOOLEAN_FALSE) )
8827 {
8828 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008829 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008830 }
8831 }
8832
8833 if (probe_rsp_ie_len[2] == 0 )
8834 {
8835 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8836 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8837 eANI_BOOLEAN_FALSE) )
8838 {
8839 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008840 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008841 }
8842 }
8843
8844 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8845 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8846 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8847 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8848 == eHAL_STATUS_FAILURE)
8849 {
8850 hddLog(LOGE,
8851 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008852 ret = -EINVAL;
8853 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008854 }
8855 }
8856 else
8857 {
8858 // Reset WNI_CFG_PROBE_RSP Flags
8859 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8860
8861 hddLog(VOS_TRACE_LEVEL_INFO,
8862 "%s: No Probe Response IE received in set beacon",
8863 __func__);
8864 }
8865
8866 // Added for AssocResp IE
8867 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
8868 {
8869 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8870 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
8871 params->assocresp_ies_len, NULL,
8872 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8873 {
8874 hddLog(LOGE,
8875 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008876 ret = -EINVAL;
8877 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008878 }
8879
8880 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8881 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8882 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8883 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8884 == eHAL_STATUS_FAILURE)
8885 {
8886 hddLog(LOGE,
8887 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008888 ret = -EINVAL;
8889 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008890 }
8891 }
8892 else
8893 {
8894 hddLog(VOS_TRACE_LEVEL_INFO,
8895 "%s: No Assoc Response IE received in set beacon",
8896 __func__);
8897
8898 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8899 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8900 eANI_BOOLEAN_FALSE) )
8901 {
8902 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008903 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008904 }
8905 }
8906
Jeff Johnsone7245742012-09-05 17:12:55 -07008907done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008908 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308909 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008910}
Jeff Johnson295189b2012-06-20 16:38:30 -07008911
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308912/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008913 * FUNCTION: wlan_hdd_validate_operation_channel
8914 * called by wlan_hdd_cfg80211_start_bss() and
8915 * wlan_hdd_cfg80211_set_channel()
8916 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308917 * channel list.
8918 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008919VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008920{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308921
Jeff Johnson295189b2012-06-20 16:38:30 -07008922 v_U32_t num_ch = 0;
8923 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8924 u32 indx = 0;
8925 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308926 v_U8_t fValidChannel = FALSE, count = 0;
8927 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308928
Jeff Johnson295189b2012-06-20 16:38:30 -07008929 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8930
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308931 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008932 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308933 /* Validate the channel */
8934 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008935 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308936 if ( channel == rfChannels[count].channelNum )
8937 {
8938 fValidChannel = TRUE;
8939 break;
8940 }
8941 }
8942 if (fValidChannel != TRUE)
8943 {
8944 hddLog(VOS_TRACE_LEVEL_ERROR,
8945 "%s: Invalid Channel [%d]", __func__, channel);
8946 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008947 }
8948 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308949 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008950 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308951 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8952 valid_ch, &num_ch))
8953 {
8954 hddLog(VOS_TRACE_LEVEL_ERROR,
8955 "%s: failed to get valid channel list", __func__);
8956 return VOS_STATUS_E_FAILURE;
8957 }
8958 for (indx = 0; indx < num_ch; indx++)
8959 {
8960 if (channel == valid_ch[indx])
8961 {
8962 break;
8963 }
8964 }
8965
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308966 if (indx >= num_ch)
8967 {
8968 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8969 {
8970 eCsrBand band;
8971 unsigned int freq;
8972
8973 sme_GetFreqBand(hHal, &band);
8974
8975 if (eCSR_BAND_5G == band)
8976 {
8977#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8978 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8979 {
8980 freq = ieee80211_channel_to_frequency(channel,
8981 IEEE80211_BAND_2GHZ);
8982 }
8983 else
8984 {
8985 freq = ieee80211_channel_to_frequency(channel,
8986 IEEE80211_BAND_5GHZ);
8987 }
8988#else
8989 freq = ieee80211_channel_to_frequency(channel);
8990#endif
8991 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
8992 return VOS_STATUS_SUCCESS;
8993 }
8994 }
8995
8996 hddLog(VOS_TRACE_LEVEL_ERROR,
8997 "%s: Invalid Channel [%d]", __func__, channel);
8998 return VOS_STATUS_E_FAILURE;
8999 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009000 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309001
Jeff Johnson295189b2012-06-20 16:38:30 -07009002 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309003
Jeff Johnson295189b2012-06-20 16:38:30 -07009004}
9005
Viral Modi3a32cc52013-02-08 11:14:52 -08009006/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309007 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009008 * This function is used to set the channel number
9009 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309010static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009011 struct ieee80211_channel *chan,
9012 enum nl80211_channel_type channel_type
9013 )
9014{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309015 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009016 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009017 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009018 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309019 hdd_context_t *pHddCtx;
9020 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009021
9022 ENTER();
9023
9024 if( NULL == dev )
9025 {
9026 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009027 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009028 return -ENODEV;
9029 }
9030 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309031
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309032 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9033 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9034 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009035 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309036 "%s: device_mode = %s (%d) freq = %d", __func__,
9037 hdd_device_modetoString(pAdapter->device_mode),
9038 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309039
9040 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9041 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309042 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009043 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309044 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009045 }
9046
9047 /*
9048 * Do freq to chan conversion
9049 * TODO: for 11a
9050 */
9051
9052 channel = ieee80211_frequency_to_channel(freq);
9053
9054 /* Check freq range */
9055 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9056 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9057 {
9058 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009059 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009060 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9061 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9062 return -EINVAL;
9063 }
9064
9065 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9066
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309067 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9068 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009069 {
9070 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9071 {
9072 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009073 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009074 return -EINVAL;
9075 }
9076 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9077 "%s: set channel to [%d] for device mode =%d",
9078 __func__, channel,pAdapter->device_mode);
9079 }
9080 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009081 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009082 )
9083 {
9084 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9085 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9086 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9087
9088 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9089 {
9090 /* Link is up then return cant set channel*/
9091 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009092 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009093 return -EINVAL;
9094 }
9095
9096 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9097 pHddStaCtx->conn_info.operationChannel = channel;
9098 pRoamProfile->ChannelInfo.ChannelList =
9099 &pHddStaCtx->conn_info.operationChannel;
9100 }
9101 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009102 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009103 )
9104 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309105 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9106 {
9107 if(VOS_STATUS_SUCCESS !=
9108 wlan_hdd_validate_operation_channel(pAdapter,channel))
9109 {
9110 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009111 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309112 return -EINVAL;
9113 }
9114 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9115 }
9116 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009117 {
9118 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9119
9120 /* If auto channel selection is configured as enable/ 1 then ignore
9121 channel set by supplicant
9122 */
9123 if ( cfg_param->apAutoChannelSelection )
9124 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309125 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9126 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009127 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309128 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9129 __func__, hdd_device_modetoString(pAdapter->device_mode),
9130 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009131 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309132 else
9133 {
9134 if(VOS_STATUS_SUCCESS !=
9135 wlan_hdd_validate_operation_channel(pAdapter,channel))
9136 {
9137 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009138 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309139 return -EINVAL;
9140 }
9141 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9142 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009143 }
9144 }
9145 else
9146 {
9147 hddLog(VOS_TRACE_LEVEL_FATAL,
9148 "%s: Invalid device mode failed to set valid channel", __func__);
9149 return -EINVAL;
9150 }
9151 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309152 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009153}
9154
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309155static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9156 struct net_device *dev,
9157 struct ieee80211_channel *chan,
9158 enum nl80211_channel_type channel_type
9159 )
9160{
9161 int ret;
9162
9163 vos_ssr_protect(__func__);
9164 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9165 vos_ssr_unprotect(__func__);
9166
9167 return ret;
9168}
9169
Jeff Johnson295189b2012-06-20 16:38:30 -07009170#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9171static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9172 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009173#else
9174static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9175 struct cfg80211_beacon_data *params,
9176 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309177 enum nl80211_hidden_ssid hidden_ssid,
9178 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009179#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009180{
9181 tsap_Config_t *pConfig;
9182 beacon_data_t *pBeacon = NULL;
9183 struct ieee80211_mgmt *pMgmt_frame;
9184 v_U8_t *pIe=NULL;
9185 v_U16_t capab_info;
9186 eCsrAuthType RSNAuthType;
9187 eCsrEncryptionType RSNEncryptType;
9188 eCsrEncryptionType mcRSNEncryptType;
9189 int status = VOS_STATUS_SUCCESS;
9190 tpWLAN_SAPEventCB pSapEventCallback;
9191 hdd_hostapd_state_t *pHostapdState;
9192 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
9193 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309194 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009195 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309196 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009197 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009198 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309199 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009200 v_BOOL_t MFPCapable = VOS_FALSE;
9201 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309202 v_BOOL_t sapEnable11AC =
9203 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07009204 ENTER();
9205
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309206 iniConfig = pHddCtx->cfg_ini;
9207
Jeff Johnson295189b2012-06-20 16:38:30 -07009208 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9209
9210 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9211
9212 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9213
9214 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9215
9216 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9217
9218 //channel is already set in the set_channel Call back
9219 //pConfig->channel = pCommitConfig->channel;
9220
9221 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309222 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009223 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9224
9225 pConfig->dtim_period = pBeacon->dtim_period;
9226
Arif Hussain6d2a3322013-11-17 19:50:10 -08009227 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009228 pConfig->dtim_period);
9229
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009230 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009231 {
9232 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009233 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309234 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9235 {
9236 tANI_BOOLEAN restartNeeded;
9237 pConfig->ieee80211d = 1;
9238 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9239 sme_setRegInfo(hHal, pConfig->countryCode);
9240 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9241 }
9242 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009243 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009244 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009245 pConfig->ieee80211d = 1;
9246 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9247 sme_setRegInfo(hHal, pConfig->countryCode);
9248 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009249 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009250 else
9251 {
9252 pConfig->ieee80211d = 0;
9253 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309254 /*
9255 * If auto channel is configured i.e. channel is 0,
9256 * so skip channel validation.
9257 */
9258 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9259 {
9260 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9261 {
9262 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009263 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309264 return -EINVAL;
9265 }
9266 }
9267 else
9268 {
9269 if(1 != pHddCtx->is_dynamic_channel_range_set)
9270 {
9271 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9272 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9273 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9274 }
9275 pHddCtx->is_dynamic_channel_range_set = 0;
9276 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009278 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009279 {
9280 pConfig->ieee80211d = 0;
9281 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309282
9283#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9284 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9285 pConfig->authType = eSAP_OPEN_SYSTEM;
9286 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9287 pConfig->authType = eSAP_SHARED_KEY;
9288 else
9289 pConfig->authType = eSAP_AUTO_SWITCH;
9290#else
9291 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9292 pConfig->authType = eSAP_OPEN_SYSTEM;
9293 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9294 pConfig->authType = eSAP_SHARED_KEY;
9295 else
9296 pConfig->authType = eSAP_AUTO_SWITCH;
9297#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009298
9299 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309300
9301 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009302 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
9303
9304 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9305
9306 /*Set wps station to configured*/
9307 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9308
9309 if(pIe)
9310 {
9311 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9312 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009313 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009314 return -EINVAL;
9315 }
9316 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9317 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009318 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009319 /* Check 15 bit of WPS IE as it contain information for wps state
9320 * WPS state
9321 */
9322 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9323 {
9324 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9325 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9326 {
9327 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9328 }
9329 }
9330 }
9331 else
9332 {
9333 pConfig->wps_state = SAP_WPS_DISABLED;
9334 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309335 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009336
c_hpothufe599e92014-06-16 11:38:55 +05309337 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9338 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9339 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9340 eCSR_ENCRYPT_TYPE_NONE;
9341
Jeff Johnson295189b2012-06-20 16:38:30 -07009342 pConfig->RSNWPAReqIELength = 0;
9343 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309344 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 WLAN_EID_RSN);
9346 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309347 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009348 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9349 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9350 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309351 /* The actual processing may eventually be more extensive than
9352 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009353 * by the app.
9354 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309355 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009356 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9357 &RSNEncryptType,
9358 &mcRSNEncryptType,
9359 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009360 &MFPCapable,
9361 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009362 pConfig->pRSNWPAReqIE[1]+2,
9363 pConfig->pRSNWPAReqIE );
9364
9365 if( VOS_STATUS_SUCCESS == status )
9366 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309367 /* Now copy over all the security attributes you have
9368 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009369 * */
9370 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9371 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9372 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9373 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309374 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009375 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009376 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9377 }
9378 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309379
Jeff Johnson295189b2012-06-20 16:38:30 -07009380 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9381 pBeacon->tail, pBeacon->tail_len);
9382
9383 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9384 {
9385 if (pConfig->pRSNWPAReqIE)
9386 {
9387 /*Mixed mode WPA/WPA2*/
9388 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
9389 pConfig->RSNWPAReqIELength += pIe[1] + 2;
9390 }
9391 else
9392 {
9393 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9394 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9395 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309396 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009397 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9398 &RSNEncryptType,
9399 &mcRSNEncryptType,
9400 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009401 &MFPCapable,
9402 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009403 pConfig->pRSNWPAReqIE[1]+2,
9404 pConfig->pRSNWPAReqIE );
9405
9406 if( VOS_STATUS_SUCCESS == status )
9407 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309408 /* Now copy over all the security attributes you have
9409 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009410 * */
9411 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9412 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9413 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9414 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309415 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009416 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009417 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9418 }
9419 }
9420 }
9421
Jeff Johnson4416a782013-03-25 14:17:50 -07009422 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
9423 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9424 return -EINVAL;
9425 }
9426
Jeff Johnson295189b2012-06-20 16:38:30 -07009427 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9428
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009429#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009430 if (params->ssid != NULL)
9431 {
9432 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9433 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9434 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9435 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9436 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009437#else
9438 if (ssid != NULL)
9439 {
9440 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9441 pConfig->SSIDinfo.ssid.length = ssid_len;
9442 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9443 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9444 }
9445#endif
9446
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309447 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009448 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309449
Jeff Johnson295189b2012-06-20 16:38:30 -07009450 /* default value */
9451 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9452 pConfig->num_accept_mac = 0;
9453 pConfig->num_deny_mac = 0;
9454
9455 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9456 pBeacon->tail, pBeacon->tail_len);
9457
9458 /* pIe for black list is following form:
9459 type : 1 byte
9460 length : 1 byte
9461 OUI : 4 bytes
9462 acl type : 1 byte
9463 no of mac addr in black list: 1 byte
9464 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309465 */
9466 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 {
9468 pConfig->SapMacaddr_acl = pIe[6];
9469 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009470 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009471 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309472 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9473 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009474 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9475 for (i = 0; i < pConfig->num_deny_mac; i++)
9476 {
9477 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9478 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309479 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009480 }
9481 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9482 pBeacon->tail, pBeacon->tail_len);
9483
9484 /* pIe for white list is following form:
9485 type : 1 byte
9486 length : 1 byte
9487 OUI : 4 bytes
9488 acl type : 1 byte
9489 no of mac addr in white list: 1 byte
9490 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309491 */
9492 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009493 {
9494 pConfig->SapMacaddr_acl = pIe[6];
9495 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009496 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009497 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309498 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9499 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009500 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9501 for (i = 0; i < pConfig->num_accept_mac; i++)
9502 {
9503 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9504 acl_entry++;
9505 }
9506 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309507
Jeff Johnson295189b2012-06-20 16:38:30 -07009508 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9509
Jeff Johnsone7245742012-09-05 17:12:55 -07009510#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009511 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309512 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9513 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309514 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9515 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009516 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9517 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309518 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9519 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009520 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309521 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009522 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309523 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009524
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309525 /* If ACS disable and selected channel <= 14
9526 * OR
9527 * ACS enabled and ACS operating band is choosen as 2.4
9528 * AND
9529 * VHT in 2.4G Disabled
9530 * THEN
9531 * Fallback to 11N mode
9532 */
9533 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9534 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309535 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309536 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009537 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309538 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9539 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009540 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9541 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009542 }
9543#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309544
Jeff Johnson295189b2012-06-20 16:38:30 -07009545 // ht_capab is not what the name conveys,this is used for protection bitmap
9546 pConfig->ht_capab =
9547 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9548
9549 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
9550 {
9551 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9552 return -EINVAL;
9553 }
9554
9555 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309556 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009557 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9558 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309559 pConfig->obssProtEnabled =
9560 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009561
Chet Lanctot8cecea22014-02-11 19:09:36 -08009562#ifdef WLAN_FEATURE_11W
9563 pConfig->mfpCapable = MFPCapable;
9564 pConfig->mfpRequired = MFPRequired;
9565 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9566 pConfig->mfpCapable, pConfig->mfpRequired);
9567#endif
9568
Arif Hussain6d2a3322013-11-17 19:50:10 -08009569 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009570 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009571 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9572 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9573 (int)pConfig->channel);
9574 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9575 pConfig->SapHw_mode, pConfig->privacy,
9576 pConfig->authType);
9577 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9578 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9579 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9580 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009581
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309582 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009583 {
9584 //Bss already started. just return.
9585 //TODO Probably it should update some beacon params.
9586 hddLog( LOGE, "Bss Already started...Ignore the request");
9587 EXIT();
9588 return 0;
9589 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309590
Agarwal Ashish51325b52014-06-16 16:50:49 +05309591 if (vos_max_concurrent_connections_reached()) {
9592 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9593 return -EINVAL;
9594 }
9595
Jeff Johnson295189b2012-06-20 16:38:30 -07009596 pConfig->persona = pHostapdAdapter->device_mode;
9597
Peng Xu2446a892014-09-05 17:21:18 +05309598 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9599 if ( NULL != psmeConfig)
9600 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309601 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309602 sme_GetConfigParam(hHal, psmeConfig);
9603 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309604#ifdef WLAN_FEATURE_AP_HT40_24G
9605 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9606 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9607 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9608 {
9609 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9610 sme_UpdateConfig (hHal, psmeConfig);
9611 }
9612#endif
Peng Xu2446a892014-09-05 17:21:18 +05309613 vos_mem_free(psmeConfig);
9614 }
Peng Xuafc34e32014-09-25 13:23:55 +05309615 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309616
Jeff Johnson295189b2012-06-20 16:38:30 -07009617 pSapEventCallback = hdd_hostapd_SAPEventCB;
9618 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9619 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9620 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009621 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009622 return -EINVAL;
9623 }
9624
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309625 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009626 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9627
9628 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309629
Jeff Johnson295189b2012-06-20 16:38:30 -07009630 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309631 {
9632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009633 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009634 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009635 VOS_ASSERT(0);
9636 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309637
Jeff Johnson295189b2012-06-20 16:38:30 -07009638 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309639 /* Initialize WMM configuation */
9640 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309641 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009642
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009643#ifdef WLAN_FEATURE_P2P_DEBUG
9644 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9645 {
9646 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9647 {
9648 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9649 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009650 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009651 }
9652 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9653 {
9654 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9655 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009656 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009657 }
9658 }
9659#endif
9660
Jeff Johnson295189b2012-06-20 16:38:30 -07009661 pHostapdState->bCommit = TRUE;
9662 EXIT();
9663
9664 return 0;
9665}
9666
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009667#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309668static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309669 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009670 struct beacon_parameters *params)
9671{
9672 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309673 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309674 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009675
9676 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309677
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309678 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9679 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9680 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309681 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9682 hdd_device_modetoString(pAdapter->device_mode),
9683 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009684
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309685 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9686 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309687 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009688 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309689 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009690 }
9691
Agarwal Ashish51325b52014-06-16 16:50:49 +05309692 if (vos_max_concurrent_connections_reached()) {
9693 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9694 return -EINVAL;
9695 }
9696
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309697 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009698 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009699 )
9700 {
9701 beacon_data_t *old,*new;
9702
9703 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309704
Jeff Johnson295189b2012-06-20 16:38:30 -07009705 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309706 {
9707 hddLog(VOS_TRACE_LEVEL_WARN,
9708 FL("already beacon info added to session(%d)"),
9709 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009710 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309711 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009712
9713 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9714
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309715 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009716 {
9717 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009718 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009719 return -EINVAL;
9720 }
9721
9722 pAdapter->sessionCtx.ap.beacon = new;
9723
9724 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9725 }
9726
9727 EXIT();
9728 return status;
9729}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309730
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309731static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9732 struct net_device *dev,
9733 struct beacon_parameters *params)
9734{
9735 int ret;
9736
9737 vos_ssr_protect(__func__);
9738 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
9739 vos_ssr_unprotect(__func__);
9740
9741 return ret;
9742}
9743
9744static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009745 struct net_device *dev,
9746 struct beacon_parameters *params)
9747{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309748 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309749 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9750 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309751 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009752
9753 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309754
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309755 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9756 TRACE_CODE_HDD_CFG80211_SET_BEACON,
9757 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
9758 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9759 __func__, hdd_device_modetoString(pAdapter->device_mode),
9760 pAdapter->device_mode);
9761
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309762 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9763 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309764 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009765 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309766 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009767 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309768
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309769 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009770 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309771 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009772 {
9773 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309774
Jeff Johnson295189b2012-06-20 16:38:30 -07009775 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309776
Jeff Johnson295189b2012-06-20 16:38:30 -07009777 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309778 {
9779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9780 FL("session(%d) old and new heads points to NULL"),
9781 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009782 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309783 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009784
9785 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9786
9787 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309788 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009789 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009790 return -EINVAL;
9791 }
9792
9793 pAdapter->sessionCtx.ap.beacon = new;
9794
9795 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9796 }
9797
9798 EXIT();
9799 return status;
9800}
9801
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309802static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
9803 struct net_device *dev,
9804 struct beacon_parameters *params)
9805{
9806 int ret;
9807
9808 vos_ssr_protect(__func__);
9809 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
9810 vos_ssr_unprotect(__func__);
9811
9812 return ret;
9813}
9814
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009815#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9816
9817#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309818static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009819 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009820#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309821static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009822 struct net_device *dev)
9823#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009824{
9825 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07009826 hdd_context_t *pHddCtx = NULL;
9827 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309828 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309829 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009830
9831 ENTER();
9832
9833 if (NULL == pAdapter)
9834 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009836 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009837 return -ENODEV;
9838 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009839
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309840 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9841 TRACE_CODE_HDD_CFG80211_STOP_AP,
9842 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309843 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9844 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309845 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009846 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309847 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07009848 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009849
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009850 pScanInfo = &pHddCtx->scan_info;
9851
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309852 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9853 __func__, hdd_device_modetoString(pAdapter->device_mode),
9854 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009855
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309856 ret = wlan_hdd_scan_abort(pAdapter);
9857
Girish Gowli4bf7a632014-06-12 13:42:11 +05309858 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07009859 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9861 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309862
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309863 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07009864 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309865 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9866 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08009867
Jeff Johnsone7245742012-09-05 17:12:55 -07009868 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309869 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07009870 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309871 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009872 }
9873
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05309874 /* Delete all associated STAs before stopping AP/P2P GO */
9875 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05309876 hdd_hostapd_stop(dev);
9877
Jeff Johnson295189b2012-06-20 16:38:30 -07009878 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009879 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009880 )
9881 {
9882 beacon_data_t *old;
9883
9884 old = pAdapter->sessionCtx.ap.beacon;
9885
9886 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309887 {
9888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9889 FL("session(%d) beacon data points to NULL"),
9890 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009891 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309892 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009893
Jeff Johnson295189b2012-06-20 16:38:30 -07009894 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009895
9896 mutex_lock(&pHddCtx->sap_lock);
9897 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9898 {
Jeff Johnson4416a782013-03-25 14:17:50 -07009899 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009900 {
9901 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9902
9903 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9904
9905 if (!VOS_IS_STATUS_SUCCESS(status))
9906 {
9907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009908 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009909 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309910 }
9911 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009912 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309913 /* BSS stopped, clear the active sessions for this device mode */
9914 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009915 }
9916 mutex_unlock(&pHddCtx->sap_lock);
9917
9918 if(status != VOS_STATUS_SUCCESS)
9919 {
9920 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009921 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009922 return -EINVAL;
9923 }
9924
Jeff Johnson4416a782013-03-25 14:17:50 -07009925 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009926 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
9927 ==eHAL_STATUS_FAILURE)
9928 {
9929 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009930 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009931 }
9932
Jeff Johnson4416a782013-03-25 14:17:50 -07009933 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009934 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9935 eANI_BOOLEAN_FALSE) )
9936 {
9937 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009938 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009939 }
9940
9941 // Reset WNI_CFG_PROBE_RSP Flags
9942 wlan_hdd_reset_prob_rspies(pAdapter);
9943
9944 pAdapter->sessionCtx.ap.beacon = NULL;
9945 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009946#ifdef WLAN_FEATURE_P2P_DEBUG
9947 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
9948 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
9949 {
9950 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
9951 "GO got removed");
9952 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
9953 }
9954#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009955 }
9956 EXIT();
9957 return status;
9958}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009959
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309960#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9961static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
9962 struct net_device *dev)
9963{
9964 int ret;
9965
9966 vos_ssr_protect(__func__);
9967 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
9968 vos_ssr_unprotect(__func__);
9969
9970 return ret;
9971}
9972#else
9973static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
9974 struct net_device *dev)
9975{
9976 int ret;
9977
9978 vos_ssr_protect(__func__);
9979 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
9980 vos_ssr_unprotect(__func__);
9981
9982 return ret;
9983}
9984#endif
9985
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009986#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
9987
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309988static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309989 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009990 struct cfg80211_ap_settings *params)
9991{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309992 hdd_adapter_t *pAdapter;
9993 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309994 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009995
9996 ENTER();
9997
Girish Gowlib143d7a2015-02-18 19:39:55 +05309998 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009999 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053010001 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010002 return -ENODEV;
10003 }
10004
10005 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10006 if (NULL == pAdapter)
10007 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010008 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010009 "%s: HDD adapter is Null", __func__);
10010 return -ENODEV;
10011 }
10012
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010013 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10014 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
10015 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010016 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
10017 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010018 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010019 "%s: HDD adapter magic is invalid", __func__);
10020 return -ENODEV;
10021 }
10022
10023 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010024 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010025 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010026 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010027 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010028 }
10029
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010030 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10031 __func__, hdd_device_modetoString(pAdapter->device_mode),
10032 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010033
10034 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010035 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010036 )
10037 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010038 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010039
10040 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010041
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010042 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010043 {
10044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10045 FL("already beacon info added to session(%d)"),
10046 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010047 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010048 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010049
Girish Gowlib143d7a2015-02-18 19:39:55 +053010050#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10051 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10052 &new,
10053 &params->beacon);
10054#else
10055 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10056 &new,
10057 &params->beacon,
10058 params->dtim_period);
10059#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010060
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010061 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010062 {
10063 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010064 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010065 return -EINVAL;
10066 }
10067 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010068#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010069 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10070#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10071 params->channel, params->channel_type);
10072#else
10073 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10074#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010075#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010076 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010077 params->ssid_len, params->hidden_ssid,
10078 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010079 }
10080
10081 EXIT();
10082 return status;
10083}
10084
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010085static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10086 struct net_device *dev,
10087 struct cfg80211_ap_settings *params)
10088{
10089 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010090
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010091 vos_ssr_protect(__func__);
10092 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10093 vos_ssr_unprotect(__func__);
10094
10095 return ret;
10096}
10097
10098static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010099 struct net_device *dev,
10100 struct cfg80211_beacon_data *params)
10101{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010102 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010103 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010104 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010105
10106 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010107
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010108 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10109 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10110 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010111 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010112 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010113
10114 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10115 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010116 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010117 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010118 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010119 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010120
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010121 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010122 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010123 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010124 {
10125 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010126
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010127 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010128
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010129 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010130 {
10131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10132 FL("session(%d) beacon data points to NULL"),
10133 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010134 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010135 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010136
10137 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10138
10139 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010140 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010141 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010142 return -EINVAL;
10143 }
10144
10145 pAdapter->sessionCtx.ap.beacon = new;
10146
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010147 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10148 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010149 }
10150
10151 EXIT();
10152 return status;
10153}
10154
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010155static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10156 struct net_device *dev,
10157 struct cfg80211_beacon_data *params)
10158{
10159 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010160
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010161 vos_ssr_protect(__func__);
10162 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10163 vos_ssr_unprotect(__func__);
10164
10165 return ret;
10166}
10167
10168#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010169
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010170static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010171 struct net_device *dev,
10172 struct bss_parameters *params)
10173{
10174 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010175 hdd_context_t *pHddCtx;
10176 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010177
10178 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010179
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010180 if (NULL == pAdapter)
10181 {
10182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10183 "%s: HDD adapter is Null", __func__);
10184 return -ENODEV;
10185 }
10186 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010187 ret = wlan_hdd_validate_context(pHddCtx);
10188 if (0 != ret)
10189 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010190 return ret;
10191 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010192 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10193 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10194 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010195 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10196 __func__, hdd_device_modetoString(pAdapter->device_mode),
10197 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010198
10199 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010200 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010201 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010202 {
10203 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10204 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010205 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010206 {
10207 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010208 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010209 }
10210
10211 EXIT();
10212 return 0;
10213}
10214
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010215static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10216 struct net_device *dev,
10217 struct bss_parameters *params)
10218{
10219 int ret;
10220
10221 vos_ssr_protect(__func__);
10222 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10223 vos_ssr_unprotect(__func__);
10224
10225 return ret;
10226}
Kiet Lam10841362013-11-01 11:36:50 +053010227/* FUNCTION: wlan_hdd_change_country_code_cd
10228* to wait for contry code completion
10229*/
10230void* wlan_hdd_change_country_code_cb(void *pAdapter)
10231{
10232 hdd_adapter_t *call_back_pAdapter = pAdapter;
10233 complete(&call_back_pAdapter->change_country_code);
10234 return NULL;
10235}
10236
Jeff Johnson295189b2012-06-20 16:38:30 -070010237/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010238 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010239 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10240 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010241int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010242 struct net_device *ndev,
10243 enum nl80211_iftype type,
10244 u32 *flags,
10245 struct vif_params *params
10246 )
10247{
10248 struct wireless_dev *wdev;
10249 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010250 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010251 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010252 tCsrRoamProfile *pRoamProfile = NULL;
10253 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010254 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010255 eMib_dot11DesiredBssType connectedBssType;
10256 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010257 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010258
10259 ENTER();
10260
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010261 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010262 {
10263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10264 "%s: Adapter context is null", __func__);
10265 return VOS_STATUS_E_FAILURE;
10266 }
10267
10268 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10269 if (!pHddCtx)
10270 {
10271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10272 "%s: HDD context is null", __func__);
10273 return VOS_STATUS_E_FAILURE;
10274 }
10275
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010276 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10277 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10278 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010279 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010280 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010281 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010282 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010283 }
10284
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010285 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10286 __func__, hdd_device_modetoString(pAdapter->device_mode),
10287 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010288
Agarwal Ashish51325b52014-06-16 16:50:49 +053010289 if (vos_max_concurrent_connections_reached()) {
10290 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10291 return -EINVAL;
10292 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010293 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010294 wdev = ndev->ieee80211_ptr;
10295
10296#ifdef WLAN_BTAMP_FEATURE
10297 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10298 (NL80211_IFTYPE_ADHOC == type)||
10299 (NL80211_IFTYPE_AP == type)||
10300 (NL80211_IFTYPE_P2P_GO == type))
10301 {
10302 pHddCtx->isAmpAllowed = VOS_FALSE;
10303 // stop AMP traffic
10304 status = WLANBAP_StopAmp();
10305 if(VOS_STATUS_SUCCESS != status )
10306 {
10307 pHddCtx->isAmpAllowed = VOS_TRUE;
10308 hddLog(VOS_TRACE_LEVEL_FATAL,
10309 "%s: Failed to stop AMP", __func__);
10310 return -EINVAL;
10311 }
10312 }
10313#endif //WLAN_BTAMP_FEATURE
10314 /* Reset the current device mode bit mask*/
10315 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10316
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010317 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10318 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10319 (type == NL80211_IFTYPE_P2P_GO)))
10320 {
10321 /* Notify Mode change in case of concurrency.
10322 * Below function invokes TDLS teardown Functionality Since TDLS is
10323 * not Supported in case of concurrency i.e Once P2P session
10324 * is detected disable offchannel and teardown TDLS links
10325 */
10326 hddLog(LOG1,
10327 FL("Device mode = %d Interface type = %d"),
10328 pAdapter->device_mode, type);
10329 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10330 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010331
Jeff Johnson295189b2012-06-20 16:38:30 -070010332 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010333 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010334 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010335 )
10336 {
10337 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010338 if (!pWextState)
10339 {
10340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10341 "%s: pWextState is null", __func__);
10342 return VOS_STATUS_E_FAILURE;
10343 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010344 pRoamProfile = &pWextState->roamProfile;
10345 LastBSSType = pRoamProfile->BSSType;
10346
10347 switch (type)
10348 {
10349 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010350 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010351 hddLog(VOS_TRACE_LEVEL_INFO,
10352 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10353 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010354#ifdef WLAN_FEATURE_11AC
10355 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10356 {
10357 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10358 }
10359#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010360 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010361 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010362 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010363 //Check for sub-string p2p to confirm its a p2p interface
10364 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010365 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010366#ifdef FEATURE_WLAN_TDLS
10367 mutex_lock(&pHddCtx->tdls_lock);
10368 wlan_hdd_tdls_exit(pAdapter, TRUE);
10369 mutex_unlock(&pHddCtx->tdls_lock);
10370#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010371 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10372 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10373 }
10374 else
10375 {
10376 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010377 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010378 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010379 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010380
Jeff Johnson295189b2012-06-20 16:38:30 -070010381 case NL80211_IFTYPE_ADHOC:
10382 hddLog(VOS_TRACE_LEVEL_INFO,
10383 "%s: setting interface Type to ADHOC", __func__);
10384 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10385 pRoamProfile->phyMode =
10386 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010387 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010388 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010389 hdd_set_ibss_ops( pAdapter );
10390 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010391
10392 status = hdd_sta_id_hash_attach(pAdapter);
10393 if (VOS_STATUS_SUCCESS != status) {
10394 hddLog(VOS_TRACE_LEVEL_ERROR,
10395 FL("Failed to initialize hash for IBSS"));
10396 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010397 break;
10398
10399 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010400 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010401 {
10402 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10403 "%s: setting interface Type to %s", __func__,
10404 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10405
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010406 //Cancel any remain on channel for GO mode
10407 if (NL80211_IFTYPE_P2P_GO == type)
10408 {
10409 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10410 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010411 if (NL80211_IFTYPE_AP == type)
10412 {
10413 /* As Loading WLAN Driver one interface being created for p2p device
10414 * address. This will take one HW STA and the max number of clients
10415 * that can connect to softAP will be reduced by one. so while changing
10416 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10417 * interface as it is not required in SoftAP mode.
10418 */
10419
10420 // Get P2P Adapter
10421 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10422
10423 if (pP2pAdapter)
10424 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010425 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010426 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010427 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10428 }
10429 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010430 //Disable IMPS & BMPS for SAP/GO
10431 if(VOS_STATUS_E_FAILURE ==
10432 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10433 {
10434 //Fail to Exit BMPS
10435 VOS_ASSERT(0);
10436 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010437
10438 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10439
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010440#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010441
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010442 /* A Mutex Lock is introduced while changing the mode to
10443 * protect the concurrent access for the Adapters by TDLS
10444 * module.
10445 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010446 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010447#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010448 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010449 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010450 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010451 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10452 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010453#ifdef FEATURE_WLAN_TDLS
10454 mutex_unlock(&pHddCtx->tdls_lock);
10455#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010456 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10457 (pConfig->apRandomBssidEnabled))
10458 {
10459 /* To meet Android requirements create a randomized
10460 MAC address of the form 02:1A:11:Fx:xx:xx */
10461 get_random_bytes(&ndev->dev_addr[3], 3);
10462 ndev->dev_addr[0] = 0x02;
10463 ndev->dev_addr[1] = 0x1A;
10464 ndev->dev_addr[2] = 0x11;
10465 ndev->dev_addr[3] |= 0xF0;
10466 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10467 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010468 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10469 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010470 }
10471
Jeff Johnson295189b2012-06-20 16:38:30 -070010472 hdd_set_ap_ops( pAdapter->dev );
10473
Kiet Lam10841362013-11-01 11:36:50 +053010474 /* This is for only SAP mode where users can
10475 * control country through ini.
10476 * P2P GO follows station country code
10477 * acquired during the STA scanning. */
10478 if((NL80211_IFTYPE_AP == type) &&
10479 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10480 {
10481 int status = 0;
10482 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10483 "%s: setting country code from INI ", __func__);
10484 init_completion(&pAdapter->change_country_code);
10485 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10486 (void *)(tSmeChangeCountryCallback)
10487 wlan_hdd_change_country_code_cb,
10488 pConfig->apCntryCode, pAdapter,
10489 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010490 eSIR_FALSE,
10491 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010492 if (eHAL_STATUS_SUCCESS == status)
10493 {
10494 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010495 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010496 &pAdapter->change_country_code,
10497 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010498 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010499 {
10500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010501 FL("SME Timed out while setting country code %ld"),
10502 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010503
10504 if (pHddCtx->isLogpInProgress)
10505 {
10506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10507 "%s: LOGP in Progress. Ignore!!!", __func__);
10508 return -EAGAIN;
10509 }
Kiet Lam10841362013-11-01 11:36:50 +053010510 }
10511 }
10512 else
10513 {
10514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010515 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010516 return -EINVAL;
10517 }
10518 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010519 status = hdd_init_ap_mode(pAdapter);
10520 if(status != VOS_STATUS_SUCCESS)
10521 {
10522 hddLog(VOS_TRACE_LEVEL_FATAL,
10523 "%s: Error initializing the ap mode", __func__);
10524 return -EINVAL;
10525 }
10526 hdd_set_conparam(1);
10527
Nirav Shah7e3c8132015-06-22 23:51:42 +053010528 status = hdd_sta_id_hash_attach(pAdapter);
10529 if (VOS_STATUS_SUCCESS != status)
10530 {
10531 hddLog(VOS_TRACE_LEVEL_ERROR,
10532 FL("Failed to initialize hash for AP"));
10533 return -EINVAL;
10534 }
10535
Jeff Johnson295189b2012-06-20 16:38:30 -070010536 /*interface type changed update in wiphy structure*/
10537 if(wdev)
10538 {
10539 wdev->iftype = type;
10540 pHddCtx->change_iface = type;
10541 }
10542 else
10543 {
10544 hddLog(VOS_TRACE_LEVEL_ERROR,
10545 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10546 return -EINVAL;
10547 }
10548 goto done;
10549 }
10550
10551 default:
10552 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10553 __func__);
10554 return -EOPNOTSUPP;
10555 }
10556 }
10557 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010558 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010559 )
10560 {
10561 switch(type)
10562 {
10563 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010564 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010565 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010566
10567 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010568#ifdef FEATURE_WLAN_TDLS
10569
10570 /* A Mutex Lock is introduced while changing the mode to
10571 * protect the concurrent access for the Adapters by TDLS
10572 * module.
10573 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010574 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010575#endif
c_hpothu002231a2015-02-05 14:58:51 +053010576 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010577 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010578 //Check for sub-string p2p to confirm its a p2p interface
10579 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010580 {
10581 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10582 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10583 }
10584 else
10585 {
10586 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010587 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010588 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010589 hdd_set_conparam(0);
10590 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010591 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10592 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010593#ifdef FEATURE_WLAN_TDLS
10594 mutex_unlock(&pHddCtx->tdls_lock);
10595#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010596 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010597 if( VOS_STATUS_SUCCESS != status )
10598 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010599 /* In case of JB, for P2P-GO, only change interface will be called,
10600 * This is the right place to enable back bmps_imps()
10601 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010602 if (pHddCtx->hdd_wlan_suspended)
10603 {
10604 hdd_set_pwrparams(pHddCtx);
10605 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010606 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010607 goto done;
10608 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010609 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010610 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010611 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10612 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010613 goto done;
10614 default:
10615 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10616 __func__);
10617 return -EOPNOTSUPP;
10618
10619 }
10620
10621 }
10622 else
10623 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010624 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10625 __func__, hdd_device_modetoString(pAdapter->device_mode),
10626 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010627 return -EOPNOTSUPP;
10628 }
10629
10630
10631 if(pRoamProfile)
10632 {
10633 if ( LastBSSType != pRoamProfile->BSSType )
10634 {
10635 /*interface type changed update in wiphy structure*/
10636 wdev->iftype = type;
10637
10638 /*the BSS mode changed, We need to issue disconnect
10639 if connected or in IBSS disconnect state*/
10640 if ( hdd_connGetConnectedBssType(
10641 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10642 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10643 {
10644 /*need to issue a disconnect to CSR.*/
10645 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10646 if( eHAL_STATUS_SUCCESS ==
10647 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10648 pAdapter->sessionId,
10649 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10650 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010651 ret = wait_for_completion_interruptible_timeout(
10652 &pAdapter->disconnect_comp_var,
10653 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10654 if (ret <= 0)
10655 {
10656 hddLog(VOS_TRACE_LEVEL_ERROR,
10657 FL("wait on disconnect_comp_var failed %ld"), ret);
10658 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010659 }
10660 }
10661 }
10662 }
10663
10664done:
10665 /*set bitmask based on updated value*/
10666 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010667
10668 /* Only STA mode support TM now
10669 * all other mode, TM feature should be disabled */
10670 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10671 (~VOS_STA & pHddCtx->concurrency_mode) )
10672 {
10673 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10674 }
10675
Jeff Johnson295189b2012-06-20 16:38:30 -070010676#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010677 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010678 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010679 {
10680 //we are ok to do AMP
10681 pHddCtx->isAmpAllowed = VOS_TRUE;
10682 }
10683#endif //WLAN_BTAMP_FEATURE
10684 EXIT();
10685 return 0;
10686}
10687
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010688/*
10689 * FUNCTION: wlan_hdd_cfg80211_change_iface
10690 * wrapper function to protect the actual implementation from SSR.
10691 */
10692int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10693 struct net_device *ndev,
10694 enum nl80211_iftype type,
10695 u32 *flags,
10696 struct vif_params *params
10697 )
10698{
10699 int ret;
10700
10701 vos_ssr_protect(__func__);
10702 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10703 vos_ssr_unprotect(__func__);
10704
10705 return ret;
10706}
10707
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010708#ifdef FEATURE_WLAN_TDLS
10709static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010710 struct net_device *dev,
10711#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10712 const u8 *mac,
10713#else
10714 u8 *mac,
10715#endif
10716 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010717{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010718 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010719 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010720 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010721 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010722 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010723 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010724
10725 ENTER();
10726
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010727 if (!dev) {
10728 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10729 return -EINVAL;
10730 }
10731
10732 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10733 if (!pAdapter) {
10734 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
10735 return -EINVAL;
10736 }
10737
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010738 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010739 {
10740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10741 "Invalid arguments");
10742 return -EINVAL;
10743 }
Hoonki Lee27511902013-03-14 18:19:06 -070010744
10745 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
10746 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
10747 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070010749 "%s: TDLS mode is disabled OR not enabled in FW."
10750 MAC_ADDRESS_STR " Request declined.",
10751 __func__, MAC_ADDR_ARRAY(mac));
10752 return -ENOTSUPP;
10753 }
10754
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010755 if (pHddCtx->isLogpInProgress)
10756 {
10757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10758 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053010759 wlan_hdd_tdls_set_link_status(pAdapter,
10760 mac,
10761 eTDLS_LINK_IDLE,
10762 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010763 return -EBUSY;
10764 }
10765
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010766 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053010767 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010768
10769 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010771 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
10772 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010773 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010774 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010775 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010776
10777 /* in add station, we accept existing valid staId if there is */
10778 if ((0 == update) &&
10779 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
10780 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010781 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010783 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010784 " link_status %d. staId %d. add station ignored.",
10785 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010786 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010787 return 0;
10788 }
10789 /* in change station, we accept only when staId is valid */
10790 if ((1 == update) &&
10791 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
10792 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
10793 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010794 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010796 "%s: " MAC_ADDRESS_STR
10797 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010798 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
10799 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
10800 mutex_unlock(&pHddCtx->tdls_lock);
10801 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010802 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010803 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010804
10805 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053010806 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010807 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10809 "%s: " MAC_ADDRESS_STR
10810 " TDLS setup is ongoing. Request declined.",
10811 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070010812 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010813 }
10814
10815 /* first to check if we reached to maximum supported TDLS peer.
10816 TODO: for now, return -EPERM looks working fine,
10817 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010818 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
10819 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010820 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10822 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010823 " TDLS Max peer already connected. Request declined."
10824 " Num of peers (%d), Max allowed (%d).",
10825 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
10826 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010827 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010828 }
10829 else
10830 {
10831 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010832 mutex_lock(&pHddCtx->tdls_lock);
10833 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010834 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010835 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010836 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10838 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
10839 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010840 return -EPERM;
10841 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010842 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010843 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010844 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053010845 wlan_hdd_tdls_set_link_status(pAdapter,
10846 mac,
10847 eTDLS_LINK_CONNECTING,
10848 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010849
Jeff Johnsond75fe012013-04-06 10:53:06 -070010850 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010851 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010852 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010854 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010855 if(StaParams->htcap_present)
10856 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010858 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010860 "ht_capa->extended_capabilities: %0x",
10861 StaParams->HTCap.extendedHtCapInfo);
10862 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010864 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010865 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010866 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010867 if(StaParams->vhtcap_present)
10868 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010870 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
10871 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
10872 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
10873 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010874 {
10875 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010877 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010879 "[%d]: %x ", i, StaParams->supported_rates[i]);
10880 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070010881 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010882 else if ((1 == update) && (NULL == StaParams))
10883 {
10884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10885 "%s : update is true, but staParams is NULL. Error!", __func__);
10886 return -EPERM;
10887 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010888
10889 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
10890
10891 if (!update)
10892 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010893 /*Before adding sta make sure that device exited from BMPS*/
10894 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
10895 {
10896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10897 "%s: Adding tdls peer sta. Disable BMPS", __func__);
10898 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10899 if (status != VOS_STATUS_SUCCESS) {
10900 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
10901 }
10902 }
10903
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010904 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010905 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010906 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010907 hddLog(VOS_TRACE_LEVEL_ERROR,
10908 FL("Failed to add TDLS peer STA. Enable Bmps"));
10909 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010910 return -EPERM;
10911 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010912 }
10913 else
10914 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010915 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010916 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010917 if (ret != eHAL_STATUS_SUCCESS) {
10918 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
10919 return -EPERM;
10920 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010921 }
10922
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010923 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010924 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
10925
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053010926 mutex_lock(&pHddCtx->tdls_lock);
10927 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
10928
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010929 if ((pTdlsPeer != NULL) &&
10930 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010931 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010932 hddLog(VOS_TRACE_LEVEL_ERROR,
10933 FL("peer link status %u"), pTdlsPeer->link_status);
10934 mutex_unlock(&pHddCtx->tdls_lock);
10935 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010936 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053010937 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010938
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010939 if (ret <= 0)
10940 {
10941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10942 "%s: timeout waiting for tdls add station indication %ld",
10943 __func__, ret);
10944 goto error;
10945 }
10946
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010947 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
10948 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010949 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010950 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010951 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010952 }
10953
10954 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070010955
10956error:
Atul Mittal115287b2014-07-08 13:26:33 +053010957 wlan_hdd_tdls_set_link_status(pAdapter,
10958 mac,
10959 eTDLS_LINK_IDLE,
10960 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010961 return -EPERM;
10962
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010963}
10964#endif
10965
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010966static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010967 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010968#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10969 const u8 *mac,
10970#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010971 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010972#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010973 struct station_parameters *params)
10974{
10975 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010976 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010977 hdd_context_t *pHddCtx;
10978 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010979 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010980 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010981#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010982 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010983 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010984 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053010985 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010986#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010987
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010988 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010989
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010990 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010991 if ((NULL == pAdapter))
10992 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010994 "invalid adapter ");
10995 return -EINVAL;
10996 }
10997
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010998 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10999 TRACE_CODE_HDD_CHANGE_STATION,
11000 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053011001 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011002
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011003 ret = wlan_hdd_validate_context(pHddCtx);
11004 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053011005 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011006 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011007 }
11008
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011009 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11010
11011 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011012 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11014 "invalid HDD station context");
11015 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011016 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011017 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
11018
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011019 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11020 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070011021 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011022 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070011023 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011024 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070011025 WLANTL_STA_AUTHENTICATED);
11026
Gopichand Nakkala29149562013-05-10 21:43:41 +053011027 if (status != VOS_STATUS_SUCCESS)
11028 {
11029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11030 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11031 return -EINVAL;
11032 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011033 }
11034 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011035 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11036 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011037#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011038 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11039 StaParams.capability = params->capability;
11040 StaParams.uapsd_queues = params->uapsd_queues;
11041 StaParams.max_sp = params->max_sp;
11042
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011043 /* Convert (first channel , number of channels) tuple to
11044 * the total list of channels. This goes with the assumption
11045 * that if the first channel is < 14, then the next channels
11046 * are an incremental of 1 else an incremental of 4 till the number
11047 * of channels.
11048 */
11049 if (0 != params->supported_channels_len) {
11050 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11051 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11052 {
11053 int wifi_chan_index;
11054 StaParams.supported_channels[j] = params->supported_channels[i];
11055 wifi_chan_index =
11056 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11057 no_of_channels = params->supported_channels[i+1];
11058 for(k=1; k <= no_of_channels; k++)
11059 {
11060 StaParams.supported_channels[j+1] =
11061 StaParams.supported_channels[j] + wifi_chan_index;
11062 j+=1;
11063 }
11064 }
11065 StaParams.supported_channels_len = j;
11066 }
11067 vos_mem_copy(StaParams.supported_oper_classes,
11068 params->supported_oper_classes,
11069 params->supported_oper_classes_len);
11070 StaParams.supported_oper_classes_len =
11071 params->supported_oper_classes_len;
11072
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011073 if (0 != params->ext_capab_len)
11074 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
11075 sizeof(StaParams.extn_capability));
11076
11077 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011078 {
11079 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011080 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011081 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011082
11083 StaParams.supported_rates_len = params->supported_rates_len;
11084
11085 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11086 * The supported_rates array , for all the structures propogating till Add Sta
11087 * to the firmware has to be modified , if the supplicant (ieee80211) is
11088 * modified to send more rates.
11089 */
11090
11091 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11092 */
11093 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11094 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11095
11096 if (0 != StaParams.supported_rates_len) {
11097 int i = 0;
11098 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11099 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011101 "Supported Rates with Length %d", StaParams.supported_rates_len);
11102 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011104 "[%d]: %0x", i, StaParams.supported_rates[i]);
11105 }
11106
11107 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011108 {
11109 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011110 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011111 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011112
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011113 if (0 != params->ext_capab_len ) {
11114 /*Define A Macro : TODO Sunil*/
11115 if ((1<<4) & StaParams.extn_capability[3]) {
11116 isBufSta = 1;
11117 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011118 /* TDLS Channel Switching Support */
11119 if ((1<<6) & StaParams.extn_capability[3]) {
11120 isOffChannelSupported = 1;
11121 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011122 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011123
11124 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011125 (params->ht_capa || params->vht_capa ||
11126 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011127 /* TDLS Peer is WME/QoS capable */
11128 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011129
11130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11131 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11132 __func__, isQosWmmSta, StaParams.htcap_present);
11133
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011134 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11135 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011136 isOffChannelSupported,
11137 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011138
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011139 if (VOS_STATUS_SUCCESS != status) {
11140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11141 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11142 return -EINVAL;
11143 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011144 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11145
11146 if (VOS_STATUS_SUCCESS != status) {
11147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11148 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11149 return -EINVAL;
11150 }
11151 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011152#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011153 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011154 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011155 return status;
11156}
11157
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011158#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11159static int wlan_hdd_change_station(struct wiphy *wiphy,
11160 struct net_device *dev,
11161 const u8 *mac,
11162 struct station_parameters *params)
11163#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011164static int wlan_hdd_change_station(struct wiphy *wiphy,
11165 struct net_device *dev,
11166 u8 *mac,
11167 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011168#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011169{
11170 int ret;
11171
11172 vos_ssr_protect(__func__);
11173 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11174 vos_ssr_unprotect(__func__);
11175
11176 return ret;
11177}
11178
Jeff Johnson295189b2012-06-20 16:38:30 -070011179/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011180 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011181 * This function is used to initialize the key information
11182 */
11183#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011184static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011185 struct net_device *ndev,
11186 u8 key_index, bool pairwise,
11187 const u8 *mac_addr,
11188 struct key_params *params
11189 )
11190#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011191static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011192 struct net_device *ndev,
11193 u8 key_index, const u8 *mac_addr,
11194 struct key_params *params
11195 )
11196#endif
11197{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011198 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011199 tCsrRoamSetKey setKey;
11200 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011201 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011202 v_U32_t roamId= 0xFF;
11203 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011204 hdd_hostapd_state_t *pHostapdState;
11205 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011206 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011207 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011208
11209 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011210
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011211 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11212 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11213 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011214 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11215 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011216 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011217 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011218 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011219 }
11220
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011221 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11222 __func__, hdd_device_modetoString(pAdapter->device_mode),
11223 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011224
11225 if (CSR_MAX_NUM_KEY <= key_index)
11226 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011227 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011228 key_index);
11229
11230 return -EINVAL;
11231 }
11232
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011233 if (CSR_MAX_KEY_LEN < params->key_len)
11234 {
11235 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11236 params->key_len);
11237
11238 return -EINVAL;
11239 }
11240
11241 hddLog(VOS_TRACE_LEVEL_INFO,
11242 "%s: called with key index = %d & key length %d",
11243 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011244
11245 /*extract key idx, key len and key*/
11246 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11247 setKey.keyId = key_index;
11248 setKey.keyLength = params->key_len;
11249 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11250
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011251 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011252 {
11253 case WLAN_CIPHER_SUITE_WEP40:
11254 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11255 break;
11256
11257 case WLAN_CIPHER_SUITE_WEP104:
11258 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11259 break;
11260
11261 case WLAN_CIPHER_SUITE_TKIP:
11262 {
11263 u8 *pKey = &setKey.Key[0];
11264 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11265
11266 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11267
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011268 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011269
11270 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011271 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011272 |--------------|----------|----------|
11273 <---16bytes---><--8bytes--><--8bytes-->
11274
11275 */
11276 /*Sme expects the 32 bytes key to be in the below order
11277
11278 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011279 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011280 |--------------|----------|----------|
11281 <---16bytes---><--8bytes--><--8bytes-->
11282 */
11283 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011284 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011285
11286 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011287 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011288
11289 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011290 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011291
11292
11293 break;
11294 }
11295
11296 case WLAN_CIPHER_SUITE_CCMP:
11297 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11298 break;
11299
11300#ifdef FEATURE_WLAN_WAPI
11301 case WLAN_CIPHER_SUITE_SMS4:
11302 {
11303 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11304 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11305 params->key, params->key_len);
11306 return 0;
11307 }
11308#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011309
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011310#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011311 case WLAN_CIPHER_SUITE_KRK:
11312 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11313 break;
11314#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011315
11316#ifdef WLAN_FEATURE_11W
11317 case WLAN_CIPHER_SUITE_AES_CMAC:
11318 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011319 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011320#endif
11321
Jeff Johnson295189b2012-06-20 16:38:30 -070011322 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011323 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011324 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011325 status = -EOPNOTSUPP;
11326 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011327 }
11328
11329 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11330 __func__, setKey.encType);
11331
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011332 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011333#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11334 (!pairwise)
11335#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011336 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011337#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011338 )
11339 {
11340 /* set group key*/
11341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11342 "%s- %d: setting Broadcast key",
11343 __func__, __LINE__);
11344 setKey.keyDirection = eSIR_RX_ONLY;
11345 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11346 }
11347 else
11348 {
11349 /* set pairwise key*/
11350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11351 "%s- %d: setting pairwise key",
11352 __func__, __LINE__);
11353 setKey.keyDirection = eSIR_TX_RX;
11354 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11355 }
11356 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11357 {
11358 setKey.keyDirection = eSIR_TX_RX;
11359 /*Set the group key*/
11360 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11361 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011362
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011363 if ( 0 != status )
11364 {
11365 hddLog(VOS_TRACE_LEVEL_ERROR,
11366 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011367 status = -EINVAL;
11368 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011369 }
11370 /*Save the keys here and call sme_RoamSetKey for setting
11371 the PTK after peer joins the IBSS network*/
11372 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11373 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011374 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011375 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011376 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11377 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11378 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011379 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011380 if( pHostapdState->bssState == BSS_START )
11381 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011382 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11383 vos_status = wlan_hdd_check_ula_done(pAdapter);
11384
11385 if ( vos_status != VOS_STATUS_SUCCESS )
11386 {
11387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11388 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11389 __LINE__, vos_status );
11390
11391 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11392
11393 status = -EINVAL;
11394 goto end;
11395 }
11396
Jeff Johnson295189b2012-06-20 16:38:30 -070011397 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11398
11399 if ( status != eHAL_STATUS_SUCCESS )
11400 {
11401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11402 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11403 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011404 status = -EINVAL;
11405 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011406 }
11407 }
11408
11409 /* Saving WEP keys */
11410 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11411 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11412 {
11413 //Save the wep key in ap context. Issue setkey after the BSS is started.
11414 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11415 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11416 }
11417 else
11418 {
11419 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011420 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011421 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11422 }
11423 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011424 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11425 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011426 {
11427 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11428 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11429
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011430#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11431 if (!pairwise)
11432#else
11433 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11434#endif
11435 {
11436 /* set group key*/
11437 if (pHddStaCtx->roam_info.deferKeyComplete)
11438 {
11439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11440 "%s- %d: Perform Set key Complete",
11441 __func__, __LINE__);
11442 hdd_PerformRoamSetKeyComplete(pAdapter);
11443 }
11444 }
11445
Jeff Johnson295189b2012-06-20 16:38:30 -070011446 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11447
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011448 pWextState->roamProfile.Keys.defaultIndex = key_index;
11449
11450
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011451 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011452 params->key, params->key_len);
11453
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011454
Jeff Johnson295189b2012-06-20 16:38:30 -070011455 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11456
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011457 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011458 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011459 __func__, setKey.peerMac[0], setKey.peerMac[1],
11460 setKey.peerMac[2], setKey.peerMac[3],
11461 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011462 setKey.keyDirection);
11463
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011464 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011465
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011466 if ( vos_status != VOS_STATUS_SUCCESS )
11467 {
11468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011469 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11470 __LINE__, vos_status );
11471
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011472 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011473
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011474 status = -EINVAL;
11475 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011476
11477 }
11478
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011479#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011480 /* The supplicant may attempt to set the PTK once pre-authentication
11481 is done. Save the key in the UMAC and include it in the ADD BSS
11482 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011483 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011484 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011485 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011486 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11487 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011488 status = 0;
11489 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011490 }
11491 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11492 {
11493 hddLog(VOS_TRACE_LEVEL_ERROR,
11494 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011495 status = -EINVAL;
11496 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011497 }
11498#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011499
11500 /* issue set key request to SME*/
11501 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11502 pAdapter->sessionId, &setKey, &roamId );
11503
11504 if ( 0 != status )
11505 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011506 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011507 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11508 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011509 status = -EINVAL;
11510 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011511 }
11512
11513
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011514 /* in case of IBSS as there was no information available about WEP keys during
11515 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011516 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011517 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11518 !( ( IW_AUTH_KEY_MGMT_802_1X
11519 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011520 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11521 )
11522 &&
11523 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11524 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11525 )
11526 )
11527 {
11528 setKey.keyDirection = eSIR_RX_ONLY;
11529 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11530
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011531 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011532 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011533 __func__, setKey.peerMac[0], setKey.peerMac[1],
11534 setKey.peerMac[2], setKey.peerMac[3],
11535 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011536 setKey.keyDirection);
11537
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011538 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011539 pAdapter->sessionId, &setKey, &roamId );
11540
11541 if ( 0 != status )
11542 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011543 hddLog(VOS_TRACE_LEVEL_ERROR,
11544 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011545 __func__, status);
11546 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011547 status = -EINVAL;
11548 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011549 }
11550 }
11551 }
11552
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011553end:
11554 /* Need to clear any trace of key value in the memory.
11555 * Thus zero out the memory even though it is local
11556 * variable.
11557 */
11558 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011559 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011560 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011561}
11562
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011563#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11564static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11565 struct net_device *ndev,
11566 u8 key_index, bool pairwise,
11567 const u8 *mac_addr,
11568 struct key_params *params
11569 )
11570#else
11571static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11572 struct net_device *ndev,
11573 u8 key_index, const u8 *mac_addr,
11574 struct key_params *params
11575 )
11576#endif
11577{
11578 int ret;
11579 vos_ssr_protect(__func__);
11580#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11581 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11582 mac_addr, params);
11583#else
11584 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11585 params);
11586#endif
11587 vos_ssr_unprotect(__func__);
11588
11589 return ret;
11590}
11591
Jeff Johnson295189b2012-06-20 16:38:30 -070011592/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011593 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011594 * This function is used to get the key information
11595 */
11596#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011597static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011598 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011599 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011600 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011601 const u8 *mac_addr, void *cookie,
11602 void (*callback)(void *cookie, struct key_params*)
11603 )
11604#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011605static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011606 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011607 struct net_device *ndev,
11608 u8 key_index, const u8 *mac_addr, void *cookie,
11609 void (*callback)(void *cookie, struct key_params*)
11610 )
11611#endif
11612{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011613 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011614 hdd_wext_state_t *pWextState = NULL;
11615 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011616 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011617 hdd_context_t *pHddCtx;
11618 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011619
11620 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011621
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011622 if (NULL == pAdapter)
11623 {
11624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11625 "%s: HDD adapter is Null", __func__);
11626 return -ENODEV;
11627 }
11628
11629 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11630 ret = wlan_hdd_validate_context(pHddCtx);
11631 if (0 != ret)
11632 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011633 return ret;
11634 }
11635
11636 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11637 pRoamProfile = &(pWextState->roamProfile);
11638
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011639 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11640 __func__, hdd_device_modetoString(pAdapter->device_mode),
11641 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011642
Jeff Johnson295189b2012-06-20 16:38:30 -070011643 memset(&params, 0, sizeof(params));
11644
11645 if (CSR_MAX_NUM_KEY <= key_index)
11646 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011647 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011648 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011649 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011650
11651 switch(pRoamProfile->EncryptionType.encryptionType[0])
11652 {
11653 case eCSR_ENCRYPT_TYPE_NONE:
11654 params.cipher = IW_AUTH_CIPHER_NONE;
11655 break;
11656
11657 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11658 case eCSR_ENCRYPT_TYPE_WEP40:
11659 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11660 break;
11661
11662 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11663 case eCSR_ENCRYPT_TYPE_WEP104:
11664 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11665 break;
11666
11667 case eCSR_ENCRYPT_TYPE_TKIP:
11668 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11669 break;
11670
11671 case eCSR_ENCRYPT_TYPE_AES:
11672 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11673 break;
11674
11675 default:
11676 params.cipher = IW_AUTH_CIPHER_NONE;
11677 break;
11678 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011679
c_hpothuaaf19692014-05-17 17:01:48 +053011680 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11681 TRACE_CODE_HDD_CFG80211_GET_KEY,
11682 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011683
Jeff Johnson295189b2012-06-20 16:38:30 -070011684 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11685 params.seq_len = 0;
11686 params.seq = NULL;
11687 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11688 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011689 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011690 return 0;
11691}
11692
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011693#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11694static int wlan_hdd_cfg80211_get_key(
11695 struct wiphy *wiphy,
11696 struct net_device *ndev,
11697 u8 key_index, bool pairwise,
11698 const u8 *mac_addr, void *cookie,
11699 void (*callback)(void *cookie, struct key_params*)
11700 )
11701#else
11702static int wlan_hdd_cfg80211_get_key(
11703 struct wiphy *wiphy,
11704 struct net_device *ndev,
11705 u8 key_index, const u8 *mac_addr, void *cookie,
11706 void (*callback)(void *cookie, struct key_params*)
11707 )
11708#endif
11709{
11710 int ret;
11711
11712 vos_ssr_protect(__func__);
11713#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11714 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
11715 mac_addr, cookie, callback);
11716#else
11717 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
11718 callback);
11719#endif
11720 vos_ssr_unprotect(__func__);
11721
11722 return ret;
11723}
11724
Jeff Johnson295189b2012-06-20 16:38:30 -070011725/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011726 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011727 * This function is used to delete the key information
11728 */
11729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011730static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011731 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011732 u8 key_index,
11733 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011734 const u8 *mac_addr
11735 )
11736#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011737static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011738 struct net_device *ndev,
11739 u8 key_index,
11740 const u8 *mac_addr
11741 )
11742#endif
11743{
11744 int status = 0;
11745
11746 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011747 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070011748 //it is observed that this is invalidating peer
11749 //key index whenever re-key is done. This is affecting data link.
11750 //It should be ok to ignore del_key.
11751#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011752 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
11753 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011754 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11755 tCsrRoamSetKey setKey;
11756 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011757
Jeff Johnson295189b2012-06-20 16:38:30 -070011758 ENTER();
11759
11760 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
11761 __func__,pAdapter->device_mode);
11762
11763 if (CSR_MAX_NUM_KEY <= key_index)
11764 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011765 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011766 key_index);
11767
11768 return -EINVAL;
11769 }
11770
11771 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11772 setKey.keyId = key_index;
11773
11774 if (mac_addr)
11775 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11776 else
11777 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
11778
11779 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
11780
11781 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011782 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011783 )
11784 {
11785
11786 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070011787 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11788 if( pHostapdState->bssState == BSS_START)
11789 {
11790 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011791
Jeff Johnson295189b2012-06-20 16:38:30 -070011792 if ( status != eHAL_STATUS_SUCCESS )
11793 {
11794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11795 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11796 __LINE__, status );
11797 }
11798 }
11799 }
11800 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011801 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070011802 )
11803 {
11804 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11805
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011806 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11807
11808 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011809 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011810 __func__, setKey.peerMac[0], setKey.peerMac[1],
11811 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070011812 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011813 if(pAdapter->sessionCtx.station.conn_info.connState ==
11814 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070011815 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011816 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011817 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011818
Jeff Johnson295189b2012-06-20 16:38:30 -070011819 if ( 0 != status )
11820 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011821 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011822 "%s: sme_RoamSetKey failure, returned %d",
11823 __func__, status);
11824 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11825 return -EINVAL;
11826 }
11827 }
11828 }
11829#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011830 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011831 return status;
11832}
11833
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011834#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11835static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11836 struct net_device *ndev,
11837 u8 key_index,
11838 bool pairwise,
11839 const u8 *mac_addr
11840 )
11841#else
11842static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11843 struct net_device *ndev,
11844 u8 key_index,
11845 const u8 *mac_addr
11846 )
11847#endif
11848{
11849 int ret;
11850
11851 vos_ssr_protect(__func__);
11852#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11853 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
11854 mac_addr);
11855#else
11856 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
11857#endif
11858 vos_ssr_unprotect(__func__);
11859
11860 return ret;
11861}
11862
Jeff Johnson295189b2012-06-20 16:38:30 -070011863/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011864 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011865 * This function is used to set the default tx key index
11866 */
11867#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011868static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011869 struct net_device *ndev,
11870 u8 key_index,
11871 bool unicast, bool multicast)
11872#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011873static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011874 struct net_device *ndev,
11875 u8 key_index)
11876#endif
11877{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011878 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011879 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011880 hdd_wext_state_t *pWextState;
11881 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011882 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011883
11884 ENTER();
11885
Gopichand Nakkala29149562013-05-10 21:43:41 +053011886 if ((NULL == pAdapter))
11887 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011889 "invalid adapter");
11890 return -EINVAL;
11891 }
11892
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011893 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11894 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
11895 pAdapter->sessionId, key_index));
11896
Gopichand Nakkala29149562013-05-10 21:43:41 +053011897 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11898 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11899
11900 if ((NULL == pWextState) || (NULL == pHddStaCtx))
11901 {
11902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11903 "invalid Wext state or HDD context");
11904 return -EINVAL;
11905 }
11906
Arif Hussain6d2a3322013-11-17 19:50:10 -080011907 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011908 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011909
Jeff Johnson295189b2012-06-20 16:38:30 -070011910 if (CSR_MAX_NUM_KEY <= key_index)
11911 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011912 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011913 key_index);
11914
11915 return -EINVAL;
11916 }
11917
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011918 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11919 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011920 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011921 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011922 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011923 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011924
Jeff Johnson295189b2012-06-20 16:38:30 -070011925 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011926 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011927 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011928 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011929 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080011930 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011931 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080011932 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070011933 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011934 {
11935 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070011936 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011937
Jeff Johnson295189b2012-06-20 16:38:30 -070011938 tCsrRoamSetKey setKey;
11939 v_U32_t roamId= 0xFF;
11940 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011941
11942 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011943 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011944
Jeff Johnson295189b2012-06-20 16:38:30 -070011945 Keys->defaultIndex = (u8)key_index;
11946 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11947 setKey.keyId = key_index;
11948 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011949
11950 vos_mem_copy(&setKey.Key[0],
11951 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011952 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011953
Gopichand Nakkala29149562013-05-10 21:43:41 +053011954 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011955
11956 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070011957 &pHddStaCtx->conn_info.bssId[0],
11958 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011959
Gopichand Nakkala29149562013-05-10 21:43:41 +053011960 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
11961 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
11962 eCSR_ENCRYPT_TYPE_WEP104)
11963 {
11964 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
11965 even though ap is configured for WEP-40 encryption. In this canse the key length
11966 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
11967 type(104) and switching encryption type to 40*/
11968 pWextState->roamProfile.EncryptionType.encryptionType[0] =
11969 eCSR_ENCRYPT_TYPE_WEP40;
11970 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
11971 eCSR_ENCRYPT_TYPE_WEP40;
11972 }
11973
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011974 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011975 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011976
Jeff Johnson295189b2012-06-20 16:38:30 -070011977 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011978 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011979 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011980
Jeff Johnson295189b2012-06-20 16:38:30 -070011981 if ( 0 != status )
11982 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011983 hddLog(VOS_TRACE_LEVEL_ERROR,
11984 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011985 status);
11986 return -EINVAL;
11987 }
11988 }
11989 }
11990
11991 /* In SoftAp mode setting key direction for default mode */
11992 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
11993 {
11994 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
11995 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
11996 (eCSR_ENCRYPT_TYPE_AES !=
11997 pWextState->roamProfile.EncryptionType.encryptionType[0])
11998 )
11999 {
12000 /* Saving key direction for default key index to TX default */
12001 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12002 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
12003 }
12004 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012005 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012006 return status;
12007}
12008
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012009#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12010static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12011 struct net_device *ndev,
12012 u8 key_index,
12013 bool unicast, bool multicast)
12014#else
12015static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12016 struct net_device *ndev,
12017 u8 key_index)
12018#endif
12019{
12020 int ret;
12021 vos_ssr_protect(__func__);
12022#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12023 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
12024 multicast);
12025#else
12026 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
12027#endif
12028 vos_ssr_unprotect(__func__);
12029
12030 return ret;
12031}
12032
Jeff Johnson295189b2012-06-20 16:38:30 -070012033/*
12034 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12035 * This function is used to inform the BSS details to nl80211 interface.
12036 */
12037static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12038 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12039{
12040 struct net_device *dev = pAdapter->dev;
12041 struct wireless_dev *wdev = dev->ieee80211_ptr;
12042 struct wiphy *wiphy = wdev->wiphy;
12043 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12044 int chan_no;
12045 int ie_length;
12046 const char *ie;
12047 unsigned int freq;
12048 struct ieee80211_channel *chan;
12049 int rssi = 0;
12050 struct cfg80211_bss *bss = NULL;
12051
Jeff Johnson295189b2012-06-20 16:38:30 -070012052 if( NULL == pBssDesc )
12053 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012054 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012055 return bss;
12056 }
12057
12058 chan_no = pBssDesc->channelId;
12059 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12060 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12061
12062 if( NULL == ie )
12063 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012064 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012065 return bss;
12066 }
12067
12068#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12069 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12070 {
12071 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12072 }
12073 else
12074 {
12075 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12076 }
12077#else
12078 freq = ieee80211_channel_to_frequency(chan_no);
12079#endif
12080
12081 chan = __ieee80211_get_channel(wiphy, freq);
12082
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012083 if (!chan) {
12084 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12085 return NULL;
12086 }
12087
Abhishek Singhaee43942014-06-16 18:55:47 +053012088 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012089
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012090 return cfg80211_inform_bss(wiphy, chan,
12091#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12092 CFG80211_BSS_FTYPE_UNKNOWN,
12093#endif
12094 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012095 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012096 pBssDesc->capabilityInfo,
12097 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012098 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012099}
12100
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012101/*
12102 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12103 * interface that BSS might have been lost.
12104 * @pAdapter: adaptor
12105 * @bssid: bssid which might have been lost
12106 *
12107 * Return: bss which is unlinked from kernel cache
12108 */
12109struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12110 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12111{
12112 struct net_device *dev = pAdapter->dev;
12113 struct wireless_dev *wdev = dev->ieee80211_ptr;
12114 struct wiphy *wiphy = wdev->wiphy;
12115 struct cfg80211_bss *bss = NULL;
12116
12117 bss = cfg80211_get_bss(wiphy, NULL, bssid,
12118 NULL,
12119 0,
12120#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && !defined(WITH_BACKPORTS) \
12121 && !defined(IEEE80211_PRIVACY)
12122 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
12123#else
12124 IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
12125#endif
12126 if (bss == NULL) {
12127 hddLog(LOGE, FL("BSS not present"));
12128 } else {
12129 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12130 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12131 cfg80211_unlink_bss(wiphy, bss);
12132 }
12133 return bss;
12134}
Jeff Johnson295189b2012-06-20 16:38:30 -070012135
12136
12137/*
12138 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12139 * This function is used to inform the BSS details to nl80211 interface.
12140 */
12141struct cfg80211_bss*
12142wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12143 tSirBssDescription *bss_desc
12144 )
12145{
12146 /*
12147 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12148 already exists in bss data base of cfg80211 for that particular BSS ID.
12149 Using cfg80211_inform_bss_frame to update the bss entry instead of
12150 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12151 now there is no possibility to get the mgmt(probe response) frame from PE,
12152 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12153 cfg80211_inform_bss_frame.
12154 */
12155 struct net_device *dev = pAdapter->dev;
12156 struct wireless_dev *wdev = dev->ieee80211_ptr;
12157 struct wiphy *wiphy = wdev->wiphy;
12158 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012159#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12160 qcom_ie_age *qie_age = NULL;
12161 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12162#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012163 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012164#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012165 const char *ie =
12166 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12167 unsigned int freq;
12168 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012169 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012170 struct cfg80211_bss *bss_status = NULL;
12171 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12172 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012173 hdd_context_t *pHddCtx;
12174 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012175#ifdef WLAN_OPEN_SOURCE
12176 struct timespec ts;
12177#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012178
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012179
Wilson Yangf80a0542013-10-07 13:02:37 -070012180 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12181 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012182 if (0 != status)
12183 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012184 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012185 }
12186
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012187 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012188 if (!mgmt)
12189 {
12190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12191 "%s: memory allocation failed ", __func__);
12192 return NULL;
12193 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012194
Jeff Johnson295189b2012-06-20 16:38:30 -070012195 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012196
12197#ifdef WLAN_OPEN_SOURCE
12198 /* Android does not want the timestamp from the frame.
12199 Instead it wants a monotonic increasing value */
12200 get_monotonic_boottime(&ts);
12201 mgmt->u.probe_resp.timestamp =
12202 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12203#else
12204 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012205 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12206 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012207
12208#endif
12209
Jeff Johnson295189b2012-06-20 16:38:30 -070012210 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12211 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012212
12213#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12214 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12215 /* Assuming this is the last IE, copy at the end */
12216 ie_length -=sizeof(qcom_ie_age);
12217 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12218 qie_age->element_id = QCOM_VENDOR_IE_ID;
12219 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12220 qie_age->oui_1 = QCOM_OUI1;
12221 qie_age->oui_2 = QCOM_OUI2;
12222 qie_age->oui_3 = QCOM_OUI3;
12223 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Deepthi Gowri4480a3f2016-05-18 19:30:17 +053012224 qie_age->age = vos_timer_get_system_time() - bss_desc->nReceivedTime;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012225#endif
12226
Jeff Johnson295189b2012-06-20 16:38:30 -070012227 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012228 if (bss_desc->fProbeRsp)
12229 {
12230 mgmt->frame_control |=
12231 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12232 }
12233 else
12234 {
12235 mgmt->frame_control |=
12236 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12237 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012238
12239#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012240 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012241 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12242 {
12243 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12244 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012245 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012246 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12247
12248 {
12249 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12250 }
12251 else
12252 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012253 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12254 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012255 kfree(mgmt);
12256 return NULL;
12257 }
12258#else
12259 freq = ieee80211_channel_to_frequency(chan_no);
12260#endif
12261 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012262 /*when the band is changed on the fly using the GUI, three things are done
12263 * 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)
12264 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12265 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12266 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12267 * and discards the channels correponding to previous band and calls back with zero bss results.
12268 * 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
12269 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12270 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12271 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12272 * So drop the bss and continue to next bss.
12273 */
12274 if(chan == NULL)
12275 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053012276 hddLog(VOS_TRACE_LEVEL_ERROR,
12277 FL("chan pointer is NULL, chan_no: %d freq: %d"),
12278 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070012279 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012280 return NULL;
12281 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012282 /*To keep the rssi icon of the connected AP in the scan window
12283 *and the rssi icon of the wireless networks in sync
12284 * */
12285 if (( eConnectionState_Associated ==
12286 pAdapter->sessionCtx.station.conn_info.connState ) &&
12287 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12288 pAdapter->sessionCtx.station.conn_info.bssId,
12289 WNI_CFG_BSSID_LEN)) &&
12290 (pHddCtx->hdd_wlan_suspended == FALSE))
12291 {
12292 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12293 rssi = (pAdapter->rssi * 100);
12294 }
12295 else
12296 {
12297 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12298 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012299
Nirav Shah20ac06f2013-12-12 18:14:06 +053012300 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012301 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12302 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012303
Jeff Johnson295189b2012-06-20 16:38:30 -070012304 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12305 frame_len, rssi, GFP_KERNEL);
12306 kfree(mgmt);
12307 return bss_status;
12308}
12309
12310/*
12311 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12312 * This function is used to update the BSS data base of CFG8011
12313 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012314struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012315 tCsrRoamInfo *pRoamInfo
12316 )
12317{
12318 tCsrRoamConnectedProfile roamProfile;
12319 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12320 struct cfg80211_bss *bss = NULL;
12321
12322 ENTER();
12323
12324 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12325 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12326
12327 if (NULL != roamProfile.pBssDesc)
12328 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012329 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12330 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012331
12332 if (NULL == bss)
12333 {
12334 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12335 __func__);
12336 }
12337
12338 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12339 }
12340 else
12341 {
12342 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12343 __func__);
12344 }
12345 return bss;
12346}
12347
12348/*
12349 * FUNCTION: wlan_hdd_cfg80211_update_bss
12350 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012351static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12352 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012353 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012354{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012355 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012356 tCsrScanResultInfo *pScanResult;
12357 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012358 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012359 tScanResultHandle pResult;
12360 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012361 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012362 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012363 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012364
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012365 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12366 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12367 NO_SESSION, pAdapter->sessionId));
12368
Wilson Yangf80a0542013-10-07 13:02:37 -070012369 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012370 ret = wlan_hdd_validate_context(pHddCtx);
12371 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070012372 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012373 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070012374 }
12375
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012376 if (pAdapter->request != NULL)
12377 {
12378 if ((pAdapter->request->n_ssids == 1)
12379 && (pAdapter->request->ssids != NULL)
12380 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12381 is_p2p_scan = true;
12382 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012383 /*
12384 * start getting scan results and populate cgf80211 BSS database
12385 */
12386 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12387
12388 /* no scan results */
12389 if (NULL == pResult)
12390 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012391 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12392 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012393 wlan_hdd_get_frame_logs(pAdapter,
12394 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012395 return status;
12396 }
12397
12398 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12399
12400 while (pScanResult)
12401 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012402 /*
12403 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12404 * entry already exists in bss data base of cfg80211 for that
12405 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12406 * bss entry instead of cfg80211_inform_bss, But this call expects
12407 * mgmt packet as input. As of now there is no possibility to get
12408 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012409 * ieee80211_mgmt(probe response) and passing to c
12410 * fg80211_inform_bss_frame.
12411 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012412 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12413 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12414 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012415 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12416 continue; //Skip the non p2p bss entries
12417 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012418 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12419 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012420
Jeff Johnson295189b2012-06-20 16:38:30 -070012421
12422 if (NULL == bss_status)
12423 {
12424 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012425 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012426 }
12427 else
12428 {
Yue Maf49ba872013-08-19 12:04:25 -070012429 cfg80211_put_bss(
12430#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12431 wiphy,
12432#endif
12433 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012434 }
12435
12436 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12437 }
12438
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012439 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012440 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012441 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012442}
12443
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012444void
12445hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12446{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012447 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012448 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012449} /****** end hddPrintMacAddr() ******/
12450
12451void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012452hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012453{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012454 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012455 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012456 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12457 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12458 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012459} /****** end hddPrintPmkId() ******/
12460
12461//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12462//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12463
12464//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12465//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12466
12467#define dump_bssid(bssid) \
12468 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012469 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12470 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012471 }
12472
12473#define dump_pmkid(pMac, pmkid) \
12474 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012475 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12476 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012477 }
12478
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012479#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012480/*
12481 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12482 * This function is used to notify the supplicant of a new PMKSA candidate.
12483 */
12484int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012485 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012486 int index, bool preauth )
12487{
Jeff Johnsone7245742012-09-05 17:12:55 -070012488#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012489 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012490 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012491
12492 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012493 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012494
12495 if( NULL == pRoamInfo )
12496 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012497 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012498 return -EINVAL;
12499 }
12500
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012501 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12502 {
12503 dump_bssid(pRoamInfo->bssid);
12504 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012505 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012506 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012507#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012508 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012509}
12510#endif //FEATURE_WLAN_LFR
12511
Yue Maef608272013-04-08 23:09:17 -070012512#ifdef FEATURE_WLAN_LFR_METRICS
12513/*
12514 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12515 * 802.11r/LFR metrics reporting function to report preauth initiation
12516 *
12517 */
12518#define MAX_LFR_METRICS_EVENT_LENGTH 100
12519VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12520 tCsrRoamInfo *pRoamInfo)
12521{
12522 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12523 union iwreq_data wrqu;
12524
12525 ENTER();
12526
12527 if (NULL == pAdapter)
12528 {
12529 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12530 return VOS_STATUS_E_FAILURE;
12531 }
12532
12533 /* create the event */
12534 memset(&wrqu, 0, sizeof(wrqu));
12535 memset(metrics_notification, 0, sizeof(metrics_notification));
12536
12537 wrqu.data.pointer = metrics_notification;
12538 wrqu.data.length = scnprintf(metrics_notification,
12539 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12540 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12541
12542 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12543
12544 EXIT();
12545
12546 return VOS_STATUS_SUCCESS;
12547}
12548
12549/*
12550 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12551 * 802.11r/LFR metrics reporting function to report preauth completion
12552 * or failure
12553 */
12554VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12555 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12556{
12557 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12558 union iwreq_data wrqu;
12559
12560 ENTER();
12561
12562 if (NULL == pAdapter)
12563 {
12564 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12565 return VOS_STATUS_E_FAILURE;
12566 }
12567
12568 /* create the event */
12569 memset(&wrqu, 0, sizeof(wrqu));
12570 memset(metrics_notification, 0, sizeof(metrics_notification));
12571
12572 scnprintf(metrics_notification, sizeof(metrics_notification),
12573 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12574 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12575
12576 if (1 == preauth_status)
12577 strncat(metrics_notification, " TRUE", 5);
12578 else
12579 strncat(metrics_notification, " FALSE", 6);
12580
12581 wrqu.data.pointer = metrics_notification;
12582 wrqu.data.length = strlen(metrics_notification);
12583
12584 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12585
12586 EXIT();
12587
12588 return VOS_STATUS_SUCCESS;
12589}
12590
12591/*
12592 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12593 * 802.11r/LFR metrics reporting function to report handover initiation
12594 *
12595 */
12596VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12597 tCsrRoamInfo *pRoamInfo)
12598{
12599 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12600 union iwreq_data wrqu;
12601
12602 ENTER();
12603
12604 if (NULL == pAdapter)
12605 {
12606 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12607 return VOS_STATUS_E_FAILURE;
12608 }
12609
12610 /* create the event */
12611 memset(&wrqu, 0, sizeof(wrqu));
12612 memset(metrics_notification, 0, sizeof(metrics_notification));
12613
12614 wrqu.data.pointer = metrics_notification;
12615 wrqu.data.length = scnprintf(metrics_notification,
12616 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12617 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12618
12619 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12620
12621 EXIT();
12622
12623 return VOS_STATUS_SUCCESS;
12624}
12625#endif
12626
Jeff Johnson295189b2012-06-20 16:38:30 -070012627/*
12628 * FUNCTION: hdd_cfg80211_scan_done_callback
12629 * scanning callback function, called after finishing scan
12630 *
12631 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012632static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012633 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12634{
12635 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012636 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012637 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012638 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012639 struct cfg80211_scan_request *req = NULL;
12640 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012641 bool aborted = false;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012642#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12643 bool iface_down = false;
12644#endif
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012645 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012646 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012647 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012648
12649 ENTER();
12650
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012651 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012652 if (NULL == pHddCtx) {
12653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012654 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012655 }
12656
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012657#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12658 if (!(pAdapter->dev->flags & IFF_UP))
12659 {
12660 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012661 iface_down = true;
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012662 }
12663#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012664 pScanInfo = &pHddCtx->scan_info;
12665
Jeff Johnson295189b2012-06-20 16:38:30 -070012666 hddLog(VOS_TRACE_LEVEL_INFO,
12667 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012668 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012669 __func__, halHandle, pContext, (int) scanId, (int) status);
12670
Kiet Lamac06e2c2013-10-23 16:25:07 +053012671 pScanInfo->mScanPendingCounter = 0;
12672
Jeff Johnson295189b2012-06-20 16:38:30 -070012673 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012674 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012675 &pScanInfo->scan_req_completion_event,
12676 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012677 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012678 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012679 hddLog(VOS_TRACE_LEVEL_ERROR,
12680 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012681 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012682 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012683 }
12684
Yue Maef608272013-04-08 23:09:17 -070012685 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012686 {
12687 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012688 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012689 }
12690
12691 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012692 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012693 {
12694 hddLog(VOS_TRACE_LEVEL_INFO,
12695 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012696 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012697 (int) scanId);
12698 }
12699
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012700#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012701 if (!iface_down)
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012702#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012703 {
12704 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
12705 pAdapter);
12706 if (0 > ret)
12707 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012708 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012709
Jeff Johnson295189b2012-06-20 16:38:30 -070012710 /* If any client wait scan result through WEXT
12711 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012712 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012713 {
12714 /* The other scan request waiting for current scan finish
12715 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012716 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012717 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012718 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012719 }
12720 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012721 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012722 {
12723 struct net_device *dev = pAdapter->dev;
12724 union iwreq_data wrqu;
12725 int we_event;
12726 char *msg;
12727
12728 memset(&wrqu, '\0', sizeof(wrqu));
12729 we_event = SIOCGIWSCAN;
12730 msg = NULL;
12731 wireless_send_event(dev, we_event, &wrqu, msg);
12732 }
12733 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012734 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012735
12736 /* Get the Scan Req */
12737 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053012738 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012739
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012740 /* Scan is no longer pending */
12741 pScanInfo->mScanPending = VOS_FALSE;
12742
mukul sharmae7041822015-12-03 15:09:21 +053012743 if (!req || req->wiphy == NULL)
Jeff Johnson295189b2012-06-20 16:38:30 -070012744 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012745 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
mukul sharmae7041822015-12-03 15:09:21 +053012746 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070012747 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012748 }
12749
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012750 /* last_scan_timestamp is used to decide if new scan
12751 * is needed or not on station interface. If last station
12752 * scan time and new station scan time is less then
12753 * last_scan_timestamp ; driver will return cached scan.
12754 */
12755 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12756 {
12757 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12758
12759 if ( req->n_channels )
12760 {
12761 for (i = 0; i < req->n_channels ; i++ )
12762 {
12763 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12764 }
12765 /* store no of channel scanned */
12766 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
12767 }
12768
12769 }
12770
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070012771 /*
12772 * cfg80211_scan_done informing NL80211 about completion
12773 * of scanning
12774 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012775 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
12776 {
12777 aborted = true;
12778 }
mukul sharmae7041822015-12-03 15:09:21 +053012779
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012780#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12781 if (!iface_down)
12782#endif
12783 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053012784
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012785 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070012786
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012787allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053012788 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
12789 ) && (pHddCtx->spoofMacAddr.isEnabled
12790 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053012791 /* Generate new random mac addr for next scan */
12792 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053012793
12794 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
12795 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053012796 }
12797
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012798 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012799 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012800
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012801 /* Acquire wakelock to handle the case where APP's tries to suspend
12802 * immediatly after the driver gets connect request(i.e after scan)
12803 * from supplicant, this result in app's is suspending and not able
12804 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012805 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012806
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012807#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12808 if (!iface_down)
12809#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012810#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012811 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012812#endif
12813
Jeff Johnson295189b2012-06-20 16:38:30 -070012814 EXIT();
12815 return 0;
12816}
12817
12818/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053012819 * FUNCTION: hdd_isConnectionInProgress
12820 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012821 *
12822 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012823v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012824{
12825 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12826 hdd_station_ctx_t *pHddStaCtx = NULL;
12827 hdd_adapter_t *pAdapter = NULL;
12828 VOS_STATUS status = 0;
12829 v_U8_t staId = 0;
12830 v_U8_t *staMac = NULL;
12831
c_hpothu9b781ba2013-12-30 20:57:45 +053012832 if (TRUE == pHddCtx->btCoexModeSet)
12833 {
12834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053012835 FL("BTCoex Mode operation in progress"));
12836 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053012837 }
12838
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012839 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12840
12841 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12842 {
12843 pAdapter = pAdapterNode->pAdapter;
12844
12845 if( pAdapter )
12846 {
12847 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012848 "%s: Adapter with device mode %s (%d) exists",
12849 __func__, hdd_device_modetoString(pAdapter->device_mode),
12850 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012851 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053012852 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12853 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
12854 (eConnectionState_Connecting ==
12855 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12856 {
12857 hddLog(VOS_TRACE_LEVEL_ERROR,
12858 "%s: %p(%d) Connection is in progress", __func__,
12859 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12860 return VOS_TRUE;
12861 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012862 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053012863 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012864 {
12865 hddLog(VOS_TRACE_LEVEL_ERROR,
12866 "%s: %p(%d) Reassociation is in progress", __func__,
12867 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12868 return VOS_TRUE;
12869 }
12870 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012871 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12872 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012873 {
12874 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12875 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012876 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012877 {
12878 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
12879 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012880 "%s: client " MAC_ADDRESS_STR
12881 " is in the middle of WPS/EAPOL exchange.", __func__,
12882 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012883 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012884 }
12885 }
12886 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
12887 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
12888 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012889 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12890 ptSapContext pSapCtx = NULL;
12891 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12892 if(pSapCtx == NULL){
12893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12894 FL("psapCtx is NULL"));
12895 return VOS_FALSE;
12896 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012897 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
12898 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012899 if ((pSapCtx->aStaInfo[staId].isUsed) &&
12900 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012901 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012902 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012903
12904 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012905 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
12906 "middle of WPS/EAPOL exchange.", __func__,
12907 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012908 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012909 }
12910 }
12911 }
12912 }
12913 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12914 pAdapterNode = pNext;
12915 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053012916 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012917}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012918
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053012919/**
12920 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
12921 * to the Scan request
12922 * @scanRequest: Pointer to the csr scan request
12923 * @request: Pointer to the scan request from supplicant
12924 *
12925 * Return: None
12926 */
12927#ifdef CFG80211_SCAN_BSSID
12928static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
12929 struct cfg80211_scan_request *request)
12930{
12931 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
12932}
12933#else
12934static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
12935 struct cfg80211_scan_request *request)
12936{
12937}
12938#endif
12939
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012940/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012941 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070012942 * this scan respond to scan trigger and update cfg80211 scan database
12943 * later, scan dump command can be used to recieve scan results
12944 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012945int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080012946#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12947 struct net_device *dev,
12948#endif
12949 struct cfg80211_scan_request *request)
12950{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012951 hdd_adapter_t *pAdapter = NULL;
12952 hdd_context_t *pHddCtx = NULL;
12953 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012954 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012955 tCsrScanRequest scanRequest;
12956 tANI_U8 *channelList = NULL, i;
12957 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012958 int status;
12959 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012960 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012961 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053012962 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053012963 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012964
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012965#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
12966 struct net_device *dev = NULL;
12967 if (NULL == request)
12968 {
12969 hddLog(VOS_TRACE_LEVEL_ERROR,
12970 "%s: scan req param null", __func__);
12971 return -EINVAL;
12972 }
12973 dev = request->wdev->netdev;
12974#endif
12975
12976 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12977 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
12978 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12979
Jeff Johnson295189b2012-06-20 16:38:30 -070012980 ENTER();
12981
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012982 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12983 __func__, hdd_device_modetoString(pAdapter->device_mode),
12984 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012985
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012986 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012987 if (0 != status)
12988 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012989 return status;
12990 }
12991
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012992 if (NULL == pwextBuf)
12993 {
12994 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
12995 __func__);
12996 return -EIO;
12997 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012998 cfg_param = pHddCtx->cfg_ini;
12999 pScanInfo = &pHddCtx->scan_info;
13000
Jeff Johnson295189b2012-06-20 16:38:30 -070013001#ifdef WLAN_BTAMP_FEATURE
13002 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013003 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013004 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013005 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013006 "%s: No scanning when AMP is on", __func__);
13007 return -EOPNOTSUPP;
13008 }
13009#endif
13010 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013011 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013012 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013013 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013014 "%s: Not scanning on device_mode = %s (%d)",
13015 __func__, hdd_device_modetoString(pAdapter->device_mode),
13016 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013017 return -EOPNOTSUPP;
13018 }
13019
13020 if (TRUE == pScanInfo->mScanPending)
13021 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013022 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13023 {
13024 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13025 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013026 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013027 }
13028
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013029 // Don't allow scan if PNO scan is going on.
13030 if (pHddCtx->isPnoEnable)
13031 {
13032 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13033 FL("pno scan in progress"));
13034 return -EBUSY;
13035 }
13036
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013037 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013038 //Channel and action frame is pending
13039 //Otherwise Cancel Remain On Channel and allow Scan
13040 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013041 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013042 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013043 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013044 return -EBUSY;
13045 }
13046
Jeff Johnson295189b2012-06-20 16:38:30 -070013047 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13048 {
13049 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013050 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013051 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013052 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013053 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13054 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013055 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013056 "%s: MAX TM Level Scan not allowed", __func__);
13057 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013058 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013059 }
13060 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13061
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013062 /* Check if scan is allowed at this point of time.
13063 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013064 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013065 {
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013066 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
13067 if (SCAN_ABORT_THRESHOLD < pHddCtx->con_scan_abort_cnt) {
13068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13069 FL("Triggering SSR, SSR status = %d"), status);
13070 vos_wlanRestart();
13071 }
13072 else
13073 pHddCtx->con_scan_abort_cnt++;
13074
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013075 return -EBUSY;
13076 }
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013077 pHddCtx->con_scan_abort_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013078
Jeff Johnson295189b2012-06-20 16:38:30 -070013079 vos_mem_zero( &scanRequest, sizeof(scanRequest));
13080
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013081 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
13082 * Becasue of this, driver is assuming that this is not wildcard scan and so
13083 * is not aging out the scan results.
13084 */
13085 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070013086 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013087 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013088 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013089
13090 if ((request->ssids) && (0 < request->n_ssids))
13091 {
13092 tCsrSSIDInfo *SsidInfo;
13093 int j;
13094 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
13095 /* Allocate num_ssid tCsrSSIDInfo structure */
13096 SsidInfo = scanRequest.SSIDs.SSIDList =
13097 ( tCsrSSIDInfo *)vos_mem_malloc(
13098 request->n_ssids*sizeof(tCsrSSIDInfo));
13099
13100 if(NULL == scanRequest.SSIDs.SSIDList)
13101 {
13102 hddLog(VOS_TRACE_LEVEL_ERROR,
13103 "%s: memory alloc failed SSIDInfo buffer", __func__);
13104 return -ENOMEM;
13105 }
13106
13107 /* copy all the ssid's and their length */
13108 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
13109 {
13110 /* get the ssid length */
13111 SsidInfo->SSID.length = request->ssids[j].ssid_len;
13112 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
13113 SsidInfo->SSID.length);
13114 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
13115 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
13116 j, SsidInfo->SSID.ssId);
13117 }
13118 /* set the scan type to active */
13119 scanRequest.scanType = eSIR_ACTIVE_SCAN;
13120 }
13121 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013122 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013123 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13124 TRACE_CODE_HDD_CFG80211_SCAN,
13125 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070013126 /* set the scan type to active */
13127 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070013128 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013129 else
13130 {
13131 /*Set the scan type to default type, in this case it is ACTIVE*/
13132 scanRequest.scanType = pScanInfo->scan_mode;
13133 }
13134 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
13135 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070013136
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013137 csr_scan_request_assign_bssid(&scanRequest, request);
13138
Jeff Johnson295189b2012-06-20 16:38:30 -070013139 /* set BSSType to default type */
13140 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
13141
13142 /*TODO: scan the requested channels only*/
13143
13144 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013145 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070013146 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013147 hddLog(VOS_TRACE_LEVEL_WARN,
13148 "No of Scan Channels exceeded limit: %d", request->n_channels);
13149 request->n_channels = MAX_CHANNEL;
13150 }
13151
13152 hddLog(VOS_TRACE_LEVEL_INFO,
13153 "No of Scan Channels: %d", request->n_channels);
13154
13155
13156 if( request->n_channels )
13157 {
13158 char chList [(request->n_channels*5)+1];
13159 int len;
13160 channelList = vos_mem_malloc( request->n_channels );
13161 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053013162 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013163 hddLog(VOS_TRACE_LEVEL_ERROR,
13164 "%s: memory alloc failed channelList", __func__);
13165 status = -ENOMEM;
13166 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053013167 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013168
13169 for( i = 0, len = 0; i < request->n_channels ; i++ )
13170 {
13171 channelList[i] = request->channels[i]->hw_value;
13172 len += snprintf(chList+len, 5, "%d ", channelList[i]);
13173 }
13174
Nirav Shah20ac06f2013-12-12 18:14:06 +053013175 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013176 "Channel-List: %s ", chList);
13177 }
c_hpothu53512302014-04-15 18:49:53 +053013178
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013179 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13180 scanRequest.ChannelInfo.ChannelList = channelList;
13181
13182 /* set requestType to full scan */
13183 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13184
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013185 /* if there is back to back scan happening in driver with in
13186 * nDeferScanTimeInterval interval driver should defer new scan request
13187 * and should provide last cached scan results instead of new channel list.
13188 * This rule is not applicable if scan is p2p scan.
13189 * This condition will work only in case when last request no of channels
13190 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013191 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013192 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013193 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013194
Sushant Kaushik86592172015-04-27 16:35:03 +053013195 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13196 /* if wps ie is NULL , then only defer scan */
13197 if ( pWpsIe == NULL &&
13198 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013199 {
13200 if ( pScanInfo->last_scan_timestamp !=0 &&
13201 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13202 {
13203 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13204 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13205 vos_mem_compare(pScanInfo->last_scan_channelList,
13206 channelList, pScanInfo->last_scan_numChannels))
13207 {
13208 hddLog(VOS_TRACE_LEVEL_WARN,
13209 " New and old station scan time differ is less then %u",
13210 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13211
13212 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013213 pAdapter);
13214
Agarwal Ashish57e84372014-12-05 18:26:53 +053013215 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013216 "Return old cached scan as all channels and no of channels are same");
13217
Agarwal Ashish57e84372014-12-05 18:26:53 +053013218 if (0 > ret)
13219 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013220
Agarwal Ashish57e84372014-12-05 18:26:53 +053013221 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013222
13223 status = eHAL_STATUS_SUCCESS;
13224 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013225 }
13226 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013227 }
13228
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013229 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13230 * search (Flush on both full scan and social scan but not on single
13231 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13232 */
13233
13234 /* Supplicant does single channel scan after 8-way handshake
13235 * and in that case driver shoudnt flush scan results. If
13236 * driver flushes the scan results here and unfortunately if
13237 * the AP doesnt respond to our probe req then association
13238 * fails which is not desired
13239 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013240 if ((request->n_ssids == 1)
13241 && (request->ssids != NULL)
13242 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13243 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013244
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013245 if( is_p2p_scan ||
13246 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013247 {
13248 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13249 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13250 pAdapter->sessionId );
13251 }
13252
13253 if( request->ie_len )
13254 {
13255 /* save this for future association (join requires this) */
13256 /*TODO: Array needs to be converted to dynamic allocation,
13257 * as multiple ie.s can be sent in cfg80211_scan_request structure
13258 * CR 597966
13259 */
13260 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13261 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13262 pScanInfo->scanAddIE.length = request->ie_len;
13263
13264 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13265 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13266 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013267 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013268 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013269 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013270 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13271 memcpy( pwextBuf->roamProfile.addIEScan,
13272 request->ie, request->ie_len);
13273 }
13274 else
13275 {
13276 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13277 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013278 }
13279
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013280 }
13281 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13282 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13283
13284 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13285 request->ie_len);
13286 if (pP2pIe != NULL)
13287 {
13288#ifdef WLAN_FEATURE_P2P_DEBUG
13289 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13290 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13291 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013292 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013293 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13294 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13295 "Go nego completed to Connection is started");
13296 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13297 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013298 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013299 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13300 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013301 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013302 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13303 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13304 "Disconnected state to Connection is started");
13305 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13306 "for 4way Handshake");
13307 }
13308#endif
13309
13310 /* no_cck will be set during p2p find to disable 11b rates */
13311 if(TRUE == request->no_cck)
13312 {
13313 hddLog(VOS_TRACE_LEVEL_INFO,
13314 "%s: This is a P2P Search", __func__);
13315 scanRequest.p2pSearch = 1;
13316
13317 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013318 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013319 /* set requestType to P2P Discovery */
13320 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13321 }
13322
13323 /*
13324 Skip Dfs Channel in case of P2P Search
13325 if it is set in ini file
13326 */
13327 if(cfg_param->skipDfsChnlInP2pSearch)
13328 {
13329 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013330 }
13331 else
13332 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013333 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013334 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013335
Agarwal Ashish4f616132013-12-30 23:32:50 +053013336 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013337 }
13338 }
13339
13340 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13341
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013342#ifdef FEATURE_WLAN_TDLS
13343 /* if tdls disagree scan right now, return immediately.
13344 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13345 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13346 */
13347 status = wlan_hdd_tdls_scan_callback (pAdapter,
13348 wiphy,
13349#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13350 dev,
13351#endif
13352 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013353 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013354 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053013355 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013356 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13357 "scan rejected %d", __func__, status);
13358 else
13359 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13360 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013361 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053013362 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013363 }
13364#endif
13365
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013366 /* acquire the wakelock to avoid the apps suspend during the scan. To
13367 * address the following issues.
13368 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13369 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13370 * for long time, this result in apps running at full power for long time.
13371 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13372 * be stuck in full power because of resume BMPS
13373 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013374 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013375
Nirav Shah20ac06f2013-12-12 18:14:06 +053013376 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13377 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013378 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13379 scanRequest.requestType, scanRequest.scanType,
13380 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013381 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13382
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013383 if (pHddCtx->spoofMacAddr.isEnabled &&
13384 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013385 {
13386 hddLog(VOS_TRACE_LEVEL_INFO,
13387 "%s: MAC Spoofing enabled for current scan", __func__);
13388 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13389 * to fill TxBds for probe request during current scan
13390 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013391 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013392 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013393
13394 if(status != VOS_STATUS_SUCCESS)
13395 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013396 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013397 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013398#ifdef FEATURE_WLAN_TDLS
13399 wlan_hdd_tdls_scan_done_callback(pAdapter);
13400#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013401 goto free_mem;
13402 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013403 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013404 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013405 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013406 pAdapter->sessionId, &scanRequest, &scanId,
13407 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013408
Jeff Johnson295189b2012-06-20 16:38:30 -070013409 if (eHAL_STATUS_SUCCESS != status)
13410 {
13411 hddLog(VOS_TRACE_LEVEL_ERROR,
13412 "%s: sme_ScanRequest returned error %d", __func__, status);
13413 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013414 if(eHAL_STATUS_RESOURCES == status)
13415 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013416 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13417 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013418 status = -EBUSY;
13419 } else {
13420 status = -EIO;
13421 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013422 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013423
13424#ifdef FEATURE_WLAN_TDLS
13425 wlan_hdd_tdls_scan_done_callback(pAdapter);
13426#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013427 goto free_mem;
13428 }
13429
13430 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013431 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013432 pAdapter->request = request;
13433 pScanInfo->scanId = scanId;
13434
13435 complete(&pScanInfo->scan_req_completion_event);
13436
13437free_mem:
13438 if( scanRequest.SSIDs.SSIDList )
13439 {
13440 vos_mem_free(scanRequest.SSIDs.SSIDList);
13441 }
13442
13443 if( channelList )
13444 vos_mem_free( channelList );
13445
13446 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013447 return status;
13448}
13449
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013450int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13451#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13452 struct net_device *dev,
13453#endif
13454 struct cfg80211_scan_request *request)
13455{
13456 int ret;
13457
13458 vos_ssr_protect(__func__);
13459 ret = __wlan_hdd_cfg80211_scan(wiphy,
13460#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13461 dev,
13462#endif
13463 request);
13464 vos_ssr_unprotect(__func__);
13465
13466 return ret;
13467}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013468
13469void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13470{
13471 v_U8_t iniDot11Mode =
13472 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13473 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13474
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013475 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13476 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013477 switch ( iniDot11Mode )
13478 {
13479 case eHDD_DOT11_MODE_AUTO:
13480 case eHDD_DOT11_MODE_11ac:
13481 case eHDD_DOT11_MODE_11ac_ONLY:
13482#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013483 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13484 sme_IsFeatureSupportedByFW(DOT11AC) )
13485 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13486 else
13487 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013488#else
13489 hddDot11Mode = eHDD_DOT11_MODE_11n;
13490#endif
13491 break;
13492 case eHDD_DOT11_MODE_11n:
13493 case eHDD_DOT11_MODE_11n_ONLY:
13494 hddDot11Mode = eHDD_DOT11_MODE_11n;
13495 break;
13496 default:
13497 hddDot11Mode = iniDot11Mode;
13498 break;
13499 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013500#ifdef WLAN_FEATURE_AP_HT40_24G
13501 if (operationChannel > SIR_11B_CHANNEL_END)
13502#endif
13503 {
13504 /* This call decides required channel bonding mode */
13505 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013506 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13507 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013508 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013509}
13510
Jeff Johnson295189b2012-06-20 16:38:30 -070013511/*
13512 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013513 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013514 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013515int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013516 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13517 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013518{
13519 int status = 0;
13520 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013521 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013522 v_U32_t roamId;
13523 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013524 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013525 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013526
13527 ENTER();
13528
13529 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013530 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13531
13532 status = wlan_hdd_validate_context(pHddCtx);
13533 if (status)
13534 {
Yue Mae36e3552014-03-05 17:06:20 -080013535 return status;
13536 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013537
Jeff Johnson295189b2012-06-20 16:38:30 -070013538 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13539 {
13540 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13541 return -EINVAL;
13542 }
13543
13544 pRoamProfile = &pWextState->roamProfile;
13545
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013546 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013547 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013548 hdd_station_ctx_t *pHddStaCtx;
13549 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013550
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013551 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13552
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013553 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013554 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13555 {
13556 /*QoS not enabled in cfg file*/
13557 pRoamProfile->uapsd_mask = 0;
13558 }
13559 else
13560 {
13561 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013562 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013563 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13564 }
13565
13566 pRoamProfile->SSIDs.numOfSSIDs = 1;
13567 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13568 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013569 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013570 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13571 ssid, ssid_len);
13572
13573 if (bssid)
13574 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013575 pValidBssid = bssid;
13576 }
13577 else if (bssid_hint)
13578 {
13579 pValidBssid = bssid_hint;
13580 }
13581 if (pValidBssid)
13582 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013583 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013584 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013585 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013586 /* Save BSSID in seperate variable as well, as RoamProfile
13587 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013588 case of join failure we should send valid BSSID to supplicant
13589 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013590 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013591 WNI_CFG_BSSID_LEN);
13592 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013593 else
13594 {
13595 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13596 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013597
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013598 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13599 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013600 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13601 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013602 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013603 /*set gen ie*/
13604 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13605 /*set auth*/
13606 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13607 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013608#ifdef FEATURE_WLAN_WAPI
13609 if (pAdapter->wapi_info.nWapiMode)
13610 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013611 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013612 switch (pAdapter->wapi_info.wapiAuthMode)
13613 {
13614 case WAPI_AUTH_MODE_PSK:
13615 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013616 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013617 pAdapter->wapi_info.wapiAuthMode);
13618 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13619 break;
13620 }
13621 case WAPI_AUTH_MODE_CERT:
13622 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013623 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013624 pAdapter->wapi_info.wapiAuthMode);
13625 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13626 break;
13627 }
13628 } // End of switch
13629 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13630 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13631 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013632 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013633 pRoamProfile->AuthType.numEntries = 1;
13634 pRoamProfile->EncryptionType.numEntries = 1;
13635 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13636 pRoamProfile->mcEncryptionType.numEntries = 1;
13637 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13638 }
13639 }
13640#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013641#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013642 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013643 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13644 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13645 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013646 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13647 sizeof (tSirGtkOffloadParams));
13648 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013649 }
13650#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013651 pRoamProfile->csrPersona = pAdapter->device_mode;
13652
Jeff Johnson32d95a32012-09-10 13:15:23 -070013653 if( operatingChannel )
13654 {
13655 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13656 pRoamProfile->ChannelInfo.numOfChannels = 1;
13657 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013658 else
13659 {
13660 pRoamProfile->ChannelInfo.ChannelList = NULL;
13661 pRoamProfile->ChannelInfo.numOfChannels = 0;
13662 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013663 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13664 {
13665 hdd_select_cbmode(pAdapter,operatingChannel);
13666 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013667
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013668 /*
13669 * Change conn_state to connecting before sme_RoamConnect(),
13670 * because sme_RoamConnect() has a direct path to call
13671 * hdd_smeRoamCallback(), which will change the conn_state
13672 * If direct path, conn_state will be accordingly changed
13673 * to NotConnected or Associated by either
13674 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13675 * in sme_RoamCallback()
13676 * if sme_RomConnect is to be queued,
13677 * Connecting state will remain until it is completed.
13678 * If connection state is not changed,
13679 * connection state will remain in eConnectionState_NotConnected state.
13680 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13681 * if conn state is eConnectionState_NotConnected.
13682 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13683 * informed of connect result indication which is an issue.
13684 */
13685
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013686 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13687 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013688 {
13689 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013690 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013691 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13692 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013693 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013694 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013695 pAdapter->sessionId, pRoamProfile, &roamId);
13696
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013697 if ((eHAL_STATUS_SUCCESS != status) &&
13698 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13699 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013700
13701 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013702 hddLog(VOS_TRACE_LEVEL_ERROR,
13703 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13704 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013705 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013706 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013707 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013708 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013709
13710 pRoamProfile->ChannelInfo.ChannelList = NULL;
13711 pRoamProfile->ChannelInfo.numOfChannels = 0;
13712
Jeff Johnson295189b2012-06-20 16:38:30 -070013713 }
13714 else
13715 {
13716 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13717 return -EINVAL;
13718 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013719 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013720 return status;
13721}
13722
13723/*
13724 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
13725 * This function is used to set the authentication type (OPEN/SHARED).
13726 *
13727 */
13728static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
13729 enum nl80211_auth_type auth_type)
13730{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013731 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013732 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13733
13734 ENTER();
13735
13736 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013737 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070013738 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013739 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013740 hddLog(VOS_TRACE_LEVEL_INFO,
13741 "%s: set authentication type to AUTOSWITCH", __func__);
13742 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
13743 break;
13744
13745 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013746#ifdef WLAN_FEATURE_VOWIFI_11R
13747 case NL80211_AUTHTYPE_FT:
13748#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013749 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013750 "%s: set authentication type to OPEN", __func__);
13751 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
13752 break;
13753
13754 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013755 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013756 "%s: set authentication type to SHARED", __func__);
13757 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
13758 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013759#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013760 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013761 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013762 "%s: set authentication type to CCKM WPA", __func__);
13763 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
13764 break;
13765#endif
13766
13767
13768 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013769 hddLog(VOS_TRACE_LEVEL_ERROR,
13770 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013771 auth_type);
13772 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
13773 return -EINVAL;
13774 }
13775
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013776 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013777 pHddStaCtx->conn_info.authType;
13778 return 0;
13779}
13780
13781/*
13782 * FUNCTION: wlan_hdd_set_akm_suite
13783 * This function is used to set the key mgmt type(PSK/8021x).
13784 *
13785 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013786static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013787 u32 key_mgmt
13788 )
13789{
13790 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13791 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053013792 /* Should be in ieee802_11_defs.h */
13793#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
13794#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070013795 /*set key mgmt type*/
13796 switch(key_mgmt)
13797 {
13798 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053013799 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013800#ifdef WLAN_FEATURE_VOWIFI_11R
13801 case WLAN_AKM_SUITE_FT_PSK:
13802#endif
13803 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070013804 __func__);
13805 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
13806 break;
13807
13808 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053013809 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013810#ifdef WLAN_FEATURE_VOWIFI_11R
13811 case WLAN_AKM_SUITE_FT_8021X:
13812#endif
13813 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070013814 __func__);
13815 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13816 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013817#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013818#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
13819#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
13820 case WLAN_AKM_SUITE_CCKM:
13821 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
13822 __func__);
13823 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
13824 break;
13825#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070013826#ifndef WLAN_AKM_SUITE_OSEN
13827#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
13828 case WLAN_AKM_SUITE_OSEN:
13829 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
13830 __func__);
13831 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13832 break;
13833#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013834
13835 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013836 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013837 __func__, key_mgmt);
13838 return -EINVAL;
13839
13840 }
13841 return 0;
13842}
13843
13844/*
13845 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013846 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070013847 * (NONE/WEP40/WEP104/TKIP/CCMP).
13848 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013849static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
13850 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070013851 bool ucast
13852 )
13853{
13854 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013855 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013856 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13857
13858 ENTER();
13859
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013860 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013861 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013862 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070013863 __func__, cipher);
13864 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13865 }
13866 else
13867 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013868
Jeff Johnson295189b2012-06-20 16:38:30 -070013869 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013870 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013871 {
13872 case IW_AUTH_CIPHER_NONE:
13873 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13874 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013875
Jeff Johnson295189b2012-06-20 16:38:30 -070013876 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013877 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070013878 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013879
Jeff Johnson295189b2012-06-20 16:38:30 -070013880 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013881 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070013882 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013883
Jeff Johnson295189b2012-06-20 16:38:30 -070013884 case WLAN_CIPHER_SUITE_TKIP:
13885 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
13886 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013887
Jeff Johnson295189b2012-06-20 16:38:30 -070013888 case WLAN_CIPHER_SUITE_CCMP:
13889 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13890 break;
13891#ifdef FEATURE_WLAN_WAPI
13892 case WLAN_CIPHER_SUITE_SMS4:
13893 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
13894 break;
13895#endif
13896
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013897#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013898 case WLAN_CIPHER_SUITE_KRK:
13899 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
13900 break;
13901#endif
13902 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013903 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013904 __func__, cipher);
13905 return -EOPNOTSUPP;
13906 }
13907 }
13908
13909 if (ucast)
13910 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013911 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013912 __func__, encryptionType);
13913 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13914 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013915 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013916 encryptionType;
13917 }
13918 else
13919 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013920 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013921 __func__, encryptionType);
13922 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
13923 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
13924 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
13925 }
13926
13927 return 0;
13928}
13929
13930
13931/*
13932 * FUNCTION: wlan_hdd_cfg80211_set_ie
13933 * This function is used to parse WPA/RSN IE's.
13934 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013935int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013936#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13937 const u8 *ie,
13938#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013939 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013940#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013941 size_t ie_len
13942 )
13943{
13944 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013945#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13946 const u8 *genie = ie;
13947#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013948 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013949#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013950 v_U16_t remLen = ie_len;
13951#ifdef FEATURE_WLAN_WAPI
13952 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
13953 u16 *tmp;
13954 v_U16_t akmsuiteCount;
13955 int *akmlist;
13956#endif
13957 ENTER();
13958
13959 /* clear previous assocAddIE */
13960 pWextState->assocAddIE.length = 0;
13961 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013962 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013963
13964 while (remLen >= 2)
13965 {
13966 v_U16_t eLen = 0;
13967 v_U8_t elementId;
13968 elementId = *genie++;
13969 eLen = *genie++;
13970 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013971
Arif Hussain6d2a3322013-11-17 19:50:10 -080013972 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070013973 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013974
13975 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070013976 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013977 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013978 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 -070013979 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013980 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013981 "%s: Invalid WPA IE", __func__);
13982 return -EINVAL;
13983 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013984 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070013985 {
13986 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013987 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013988 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013989
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013990 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013991 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013992 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
13993 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013994 VOS_ASSERT(0);
13995 return -ENOMEM;
13996 }
13997 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13998 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13999 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014000
Jeff Johnson295189b2012-06-20 16:38:30 -070014001 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
14002 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14003 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14004 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014005 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
14006 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014007 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
14008 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14009 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
14010 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
14011 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
14012 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014013 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053014014 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070014015 {
14016 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014017 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014018 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014019
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014020 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014021 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014022 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14023 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014024 VOS_ASSERT(0);
14025 return -ENOMEM;
14026 }
14027 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14028 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14029 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014030
Jeff Johnson295189b2012-06-20 16:38:30 -070014031 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14032 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14033 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014034#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014035 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
14036 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014037 /*Consider WFD IE, only for P2P Client */
14038 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
14039 {
14040 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014041 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014042 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014043
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014044 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014045 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014046 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14047 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014048 VOS_ASSERT(0);
14049 return -ENOMEM;
14050 }
14051 // WFD IE is saved to Additional IE ; it should be accumulated to handle
14052 // WPS IE + P2P IE + WFD IE
14053 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14054 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014055
Jeff Johnson295189b2012-06-20 16:38:30 -070014056 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14057 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14058 }
14059#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014060 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014061 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014062 HS20_OUI_TYPE_SIZE)) )
14063 {
14064 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014065 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014066 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014067
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014068 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014069 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014070 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14071 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014072 VOS_ASSERT(0);
14073 return -ENOMEM;
14074 }
14075 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14076 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014077
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014078 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14079 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14080 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014081 /* Appending OSEN Information Element in Assiciation Request */
14082 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
14083 OSEN_OUI_TYPE_SIZE)) )
14084 {
14085 v_U16_t curAddIELen = pWextState->assocAddIE.length;
14086 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
14087 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014088
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014089 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014090 {
14091 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14092 "Need bigger buffer space");
14093 VOS_ASSERT(0);
14094 return -ENOMEM;
14095 }
14096 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14097 pWextState->assocAddIE.length += eLen + 2;
14098
14099 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
14100 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14101 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14102 }
14103
Abhishek Singh4322e622015-06-10 15:42:54 +053014104 /* Update only for WPA IE */
14105 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
14106 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014107
14108 /* populating as ADDIE in beacon frames */
14109 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014110 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014111 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
14112 {
14113 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14114 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
14115 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14116 {
14117 hddLog(LOGE,
14118 "Coldn't pass "
14119 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
14120 }
14121 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
14122 else
14123 hddLog(LOGE,
14124 "Could not pass on "
14125 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
14126
14127 /* IBSS mode doesn't contain params->proberesp_ies still
14128 beaconIE's need to be populated in probe response frames */
14129 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
14130 {
14131 u16 rem_probe_resp_ie_len = eLen + 2;
14132 u8 probe_rsp_ie_len[3] = {0};
14133 u8 counter = 0;
14134
14135 /* Check Probe Resp Length if it is greater then 255 then
14136 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
14137 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
14138 not able Store More then 255 bytes into One Variable */
14139
14140 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
14141 {
14142 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
14143 {
14144 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
14145 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
14146 }
14147 else
14148 {
14149 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
14150 rem_probe_resp_ie_len = 0;
14151 }
14152 }
14153
14154 rem_probe_resp_ie_len = 0;
14155
14156 if (probe_rsp_ie_len[0] > 0)
14157 {
14158 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14159 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
14160 (tANI_U8*)(genie - 2),
14161 probe_rsp_ie_len[0], NULL,
14162 eANI_BOOLEAN_FALSE)
14163 == eHAL_STATUS_FAILURE)
14164 {
14165 hddLog(LOGE,
14166 "Could not pass"
14167 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
14168 }
14169 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
14170 }
14171
14172 if (probe_rsp_ie_len[1] > 0)
14173 {
14174 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14175 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
14176 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14177 probe_rsp_ie_len[1], NULL,
14178 eANI_BOOLEAN_FALSE)
14179 == eHAL_STATUS_FAILURE)
14180 {
14181 hddLog(LOGE,
14182 "Could not pass"
14183 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14184 }
14185 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14186 }
14187
14188 if (probe_rsp_ie_len[2] > 0)
14189 {
14190 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14191 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14192 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14193 probe_rsp_ie_len[2], NULL,
14194 eANI_BOOLEAN_FALSE)
14195 == eHAL_STATUS_FAILURE)
14196 {
14197 hddLog(LOGE,
14198 "Could not pass"
14199 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14200 }
14201 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14202 }
14203
14204 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14205 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14206 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14207 {
14208 hddLog(LOGE,
14209 "Could not pass"
14210 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14211 }
14212 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014213 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014214 break;
14215 case DOT11F_EID_RSN:
14216 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14217 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14218 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14219 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14220 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14221 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014222
Abhishek Singhb16f3562016-01-20 11:08:32 +053014223 /* Appending extended capabilities with Interworking or
14224 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053014225 *
14226 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053014227 * interworkingService or bsstransition bit is set to 1.
14228 * Driver is only interested in interworkingService and
14229 * bsstransition capability from supplicant.
14230 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053014231 * required from supplicat, it needs to be handled while
14232 * sending Assoc Req in LIM.
14233 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014234 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014235 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014236 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014237 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014238 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014239
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014240 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014241 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014242 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14243 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014244 VOS_ASSERT(0);
14245 return -ENOMEM;
14246 }
14247 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14248 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014249
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014250 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14251 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14252 break;
14253 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014254#ifdef FEATURE_WLAN_WAPI
14255 case WLAN_EID_WAPI:
14256 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014257 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014258 pAdapter->wapi_info.nWapiMode);
14259 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014260 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014261 akmsuiteCount = WPA_GET_LE16(tmp);
14262 tmp = tmp + 1;
14263 akmlist = (int *)(tmp);
14264 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14265 {
14266 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14267 }
14268 else
14269 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014270 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014271 VOS_ASSERT(0);
14272 return -EINVAL;
14273 }
14274
14275 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14276 {
14277 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014278 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014279 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014280 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014281 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014282 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014283 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014284 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014285 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14286 }
14287 break;
14288#endif
14289 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014290 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014291 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014292 /* when Unknown IE is received we should break and continue
14293 * to the next IE in the buffer instead we were returning
14294 * so changing this to break */
14295 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014296 }
14297 genie += eLen;
14298 remLen -= eLen;
14299 }
14300 EXIT();
14301 return 0;
14302}
14303
14304/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014305 * FUNCTION: hdd_isWPAIEPresent
14306 * Parse the received IE to find the WPA IE
14307 *
14308 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014309static bool hdd_isWPAIEPresent(
14310#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14311 const u8 *ie,
14312#else
14313 u8 *ie,
14314#endif
14315 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014316{
14317 v_U8_t eLen = 0;
14318 v_U16_t remLen = ie_len;
14319 v_U8_t elementId = 0;
14320
14321 while (remLen >= 2)
14322 {
14323 elementId = *ie++;
14324 eLen = *ie++;
14325 remLen -= 2;
14326 if (eLen > remLen)
14327 {
14328 hddLog(VOS_TRACE_LEVEL_ERROR,
14329 "%s: IE length is wrong %d", __func__, eLen);
14330 return FALSE;
14331 }
14332 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14333 {
14334 /* OUI - 0x00 0X50 0XF2
14335 WPA Information Element - 0x01
14336 WPA version - 0x01*/
14337 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14338 return TRUE;
14339 }
14340 ie += eLen;
14341 remLen -= eLen;
14342 }
14343 return FALSE;
14344}
14345
14346/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014347 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014348 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014349 * parameters during connect operation.
14350 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014351int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014352 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014353 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014354{
14355 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014356 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014357 ENTER();
14358
14359 /*set wpa version*/
14360 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14361
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014362 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014363 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014364 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014365 {
14366 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14367 }
14368 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14369 {
14370 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14371 }
14372 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014373
14374 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014375 pWextState->wpaVersion);
14376
14377 /*set authentication type*/
14378 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14379
14380 if (0 > status)
14381 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014382 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014383 "%s: failed to set authentication type ", __func__);
14384 return status;
14385 }
14386
14387 /*set key mgmt type*/
14388 if (req->crypto.n_akm_suites)
14389 {
14390 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14391 if (0 > status)
14392 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014393 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014394 __func__);
14395 return status;
14396 }
14397 }
14398
14399 /*set pairwise cipher type*/
14400 if (req->crypto.n_ciphers_pairwise)
14401 {
14402 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14403 req->crypto.ciphers_pairwise[0], true);
14404 if (0 > status)
14405 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014406 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014407 "%s: failed to set unicast cipher type", __func__);
14408 return status;
14409 }
14410 }
14411 else
14412 {
14413 /*Reset previous cipher suite to none*/
14414 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14415 if (0 > status)
14416 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014417 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014418 "%s: failed to set unicast cipher type", __func__);
14419 return status;
14420 }
14421 }
14422
14423 /*set group cipher type*/
14424 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14425 false);
14426
14427 if (0 > status)
14428 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014429 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014430 __func__);
14431 return status;
14432 }
14433
Chet Lanctot186b5732013-03-18 10:26:30 -070014434#ifdef WLAN_FEATURE_11W
14435 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14436#endif
14437
Jeff Johnson295189b2012-06-20 16:38:30 -070014438 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14439 if (req->ie_len)
14440 {
14441 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14442 if ( 0 > status)
14443 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014444 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014445 __func__);
14446 return status;
14447 }
14448 }
14449
14450 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014451 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014452 {
14453 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14454 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14455 )
14456 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014457 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014458 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14459 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014460 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014461 __func__);
14462 return -EOPNOTSUPP;
14463 }
14464 else
14465 {
14466 u8 key_len = req->key_len;
14467 u8 key_idx = req->key_idx;
14468
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014469 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014470 && (CSR_MAX_NUM_KEY > key_idx)
14471 )
14472 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014473 hddLog(VOS_TRACE_LEVEL_INFO,
14474 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014475 __func__, key_idx, key_len);
14476 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014477 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014478 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014479 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014480 (u8)key_len;
14481 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14482 }
14483 }
14484 }
14485 }
14486
14487 return status;
14488}
14489
14490/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014491 * FUNCTION: wlan_hdd_try_disconnect
14492 * This function is used to disconnect from previous
14493 * connection
14494 */
14495static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14496{
14497 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014498 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014499 hdd_station_ctx_t *pHddStaCtx;
14500 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014501 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014502
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014503 ret = wlan_hdd_validate_context(pHddCtx);
14504 if (0 != ret)
14505 {
14506 return ret;
14507 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014508 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14509
14510 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14511
14512 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14513 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053014514 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014515 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14516 {
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014517 spin_lock_bh(&pAdapter->lock_for_active_session);
14518 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14519 {
14520 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14521 }
14522 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053014523 hdd_connSetConnectionState(pHddStaCtx,
14524 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014525 /* Issue disconnect to CSR */
14526 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014527 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014528 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014529 eCSR_DISCONNECT_REASON_UNSPECIFIED);
14530 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
14531 hddLog(LOG1,
14532 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
14533 } else if ( 0 != status ) {
14534 hddLog(LOGE,
14535 FL("csrRoamDisconnect failure, returned %d"),
14536 (int)status );
14537 result = -EINVAL;
14538 goto disconnected;
14539 }
14540 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014541 &pAdapter->disconnect_comp_var,
14542 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014543 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
14544 hddLog(LOGE,
14545 "%s: Failed to disconnect, timed out", __func__);
14546 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014547 }
14548 }
14549 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14550 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014551 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014552 &pAdapter->disconnect_comp_var,
14553 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014554 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014555 {
14556 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014557 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014558 }
14559 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014560disconnected:
14561 hddLog(LOG1,
14562 FL("Set HDD connState to eConnectionState_NotConnected"));
14563 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14564 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014565}
14566
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014567/**
14568 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
14569 * @adapter: Pointer to the HDD adapter
14570 * @req: Pointer to the structure cfg_connect_params receieved from user space
14571 *
14572 * This function will start reassociation if bssid hint, channel hint and
14573 * previous bssid parameters are present in the connect request
14574 *
14575 * Return: success if reassociation is happening
14576 * Error code if reassociation is not permitted or not happening
14577 */
14578#ifdef CFG80211_CONNECT_PREV_BSSID
14579static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14580 struct cfg80211_connect_params *req)
14581{
14582 int status = -EPERM;
14583 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
14584 hddLog(VOS_TRACE_LEVEL_INFO,
14585 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
14586 req->channel_hint->hw_value,
14587 MAC_ADDR_ARRAY(req->bssid_hint));
14588 status = hdd_reassoc(adapter, req->bssid_hint,
14589 req->channel_hint->hw_value,
14590 CONNECT_CMD_USERSPACE);
14591 }
14592 return status;
14593}
14594#else
14595static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14596 struct cfg80211_connect_params *req)
14597{
14598 return -EPERM;
14599}
14600#endif
14601
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014602/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014603 * FUNCTION: __wlan_hdd_cfg80211_connect
14604 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014605 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014606static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014607 struct net_device *ndev,
14608 struct cfg80211_connect_params *req
14609 )
14610{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014611 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014612 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053014613#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
14614 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014615 const u8 *bssid_hint = req->bssid_hint;
14616#else
14617 const u8 *bssid_hint = NULL;
14618#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014619 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014620 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014621 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014622
14623 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014624
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014625 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14626 TRACE_CODE_HDD_CFG80211_CONNECT,
14627 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014628 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014629 "%s: device_mode = %s (%d)", __func__,
14630 hdd_device_modetoString(pAdapter->device_mode),
14631 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014632
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014633 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014634 if (!pHddCtx)
14635 {
14636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14637 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014638 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014639 }
14640
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014641 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014642 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014643 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014644 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014645 }
14646
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014647 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
14648 if (0 == status)
14649 return status;
14650
Agarwal Ashish51325b52014-06-16 16:50:49 +053014651
Jeff Johnson295189b2012-06-20 16:38:30 -070014652#ifdef WLAN_BTAMP_FEATURE
14653 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014654 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014655 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014656 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014657 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014658 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014659 }
14660#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014661
14662 //If Device Mode is Station Concurrent Sessions Exit BMps
14663 //P2P Mode will be taken care in Open/close adapter
14664 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014665 (vos_concurrent_open_sessions_running())) {
14666 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14667 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014668 }
14669
14670 /*Try disconnecting if already in connected state*/
14671 status = wlan_hdd_try_disconnect(pAdapter);
14672 if ( 0 > status)
14673 {
14674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14675 " connection"));
14676 return -EALREADY;
14677 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053014678 /* Check for max concurrent connections after doing disconnect if any*/
14679 if (vos_max_concurrent_connections_reached()) {
14680 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14681 return -ECONNREFUSED;
14682 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014683
Jeff Johnson295189b2012-06-20 16:38:30 -070014684 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014685 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014686
14687 if ( 0 > status)
14688 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014689 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014690 __func__);
14691 return status;
14692 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053014693
14694 if (pHddCtx->spoofMacAddr.isEnabled)
14695 {
14696 hddLog(VOS_TRACE_LEVEL_INFO,
14697 "%s: MAC Spoofing enabled ", __func__);
14698 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14699 * to fill TxBds for probe request during SSID scan which may happen
14700 * as part of connect command
14701 */
14702 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
14703 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
14704 if (status != VOS_STATUS_SUCCESS)
14705 return -ECONNREFUSED;
14706 }
14707
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014708 if (req->channel)
14709 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070014710 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014711 channel = 0;
14712 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14713 req->ssid_len, req->bssid,
14714 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014715
Sushant Kaushikd7083982015-03-18 14:33:24 +053014716 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014717 {
14718 //ReEnable BMPS if disabled
14719 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
14720 (NULL != pHddCtx))
14721 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053014722 if (pHddCtx->hdd_wlan_suspended)
14723 {
14724 hdd_set_pwrparams(pHddCtx);
14725 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014726 //ReEnable Bmps and Imps back
14727 hdd_enable_bmps_imps(pHddCtx);
14728 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014729 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070014730 return status;
14731 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014732 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014733 EXIT();
14734 return status;
14735}
14736
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014737static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
14738 struct net_device *ndev,
14739 struct cfg80211_connect_params *req)
14740{
14741 int ret;
14742 vos_ssr_protect(__func__);
14743 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
14744 vos_ssr_unprotect(__func__);
14745
14746 return ret;
14747}
Jeff Johnson295189b2012-06-20 16:38:30 -070014748
14749/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014750 * FUNCTION: wlan_hdd_disconnect
14751 * This function is used to issue a disconnect request to SME
14752 */
14753int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
14754{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014755 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014756 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014757 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014758 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014759
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014760 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014761
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014762 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014763 if (0 != status)
14764 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014765 return status;
14766 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053014767 /* Indicate sme of disconnect so that in progress connection or preauth
14768 * can be aborted
14769 */
14770 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053014771 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014772 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014773
Agarwal Ashish47d18112014-08-04 19:55:07 +053014774 /* Need to apply spin lock before decreasing active sessions
14775 * as there can be chance for double decrement if context switch
14776 * Calls hdd_DisConnectHandler.
14777 */
14778
14779 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014780 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14781 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014782 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14783 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053014784 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
14785 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014786
Abhishek Singhf4669da2014-05-26 15:07:49 +053014787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053014788 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
14789
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014790 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014791
Mihir Shete182a0b22014-08-18 16:08:48 +053014792 /*
14793 * stop tx queues before deleting STA/BSS context from the firmware.
14794 * tx has to be disabled because the firmware can get busy dropping
14795 * the tx frames after BSS/STA has been deleted and will not send
14796 * back a response resulting in WDI timeout
14797 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053014798 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053014799 netif_tx_disable(pAdapter->dev);
14800 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014801
Mihir Shete182a0b22014-08-18 16:08:48 +053014802 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014803 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14804 pAdapter->sessionId, reason);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014805 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
14806 {
14807 hddLog(LOG1,
14808 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014809 }
14810 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014811 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014812 hddLog(LOGE,
14813 FL("csrRoamDisconnect failure, returned %d"),
14814 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014815 result = -EINVAL;
14816 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014817 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014818 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014819 &pAdapter->disconnect_comp_var,
14820 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014821 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014822 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014823 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014824 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014825 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014826 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014827disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014828 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014829 FL("Set HDD connState to eConnectionState_NotConnected"));
14830 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053014831#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
14832 /* Sending disconnect event to userspace for kernel version < 3.11
14833 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
14834 */
14835 hddLog(LOG1, FL("Send disconnected event to userspace"));
14836
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053014837 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053014838 WLAN_REASON_UNSPECIFIED);
14839#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014840
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014841 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014842 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014843}
14844
14845
14846/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014847 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070014848 * This function is used to issue a disconnect request to SME
14849 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014850static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014851 struct net_device *dev,
14852 u16 reason
14853 )
14854{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014855 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014856 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014857 tCsrRoamProfile *pRoamProfile;
14858 hdd_station_ctx_t *pHddStaCtx;
14859 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014860#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014861 tANI_U8 staIdx;
14862#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014863
Jeff Johnson295189b2012-06-20 16:38:30 -070014864 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014865
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014866 if (!pAdapter) {
14867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14868 return -EINVAL;
14869 }
14870
14871 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14872 if (!pHddStaCtx) {
14873 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
14874 return -EINVAL;
14875 }
14876
14877 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14878 status = wlan_hdd_validate_context(pHddCtx);
14879 if (0 != status)
14880 {
14881 return status;
14882 }
14883
14884 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
14885
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014886 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14887 TRACE_CODE_HDD_CFG80211_DISCONNECT,
14888 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014889 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
14890 __func__, hdd_device_modetoString(pAdapter->device_mode),
14891 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014892
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014893 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
14894 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070014895
Jeff Johnson295189b2012-06-20 16:38:30 -070014896 if (NULL != pRoamProfile)
14897 {
14898 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014899 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
14900 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070014901 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014902 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070014903 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014904 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014905 switch(reason)
14906 {
14907 case WLAN_REASON_MIC_FAILURE:
14908 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
14909 break;
14910
14911 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
14912 case WLAN_REASON_DISASSOC_AP_BUSY:
14913 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
14914 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
14915 break;
14916
14917 case WLAN_REASON_PREV_AUTH_NOT_VALID:
14918 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053014919 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070014920 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
14921 break;
14922
Jeff Johnson295189b2012-06-20 16:38:30 -070014923 default:
14924 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
14925 break;
14926 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014927 pScanInfo = &pHddCtx->scan_info;
14928 if (pScanInfo->mScanPending)
14929 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014930 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014931 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014932 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014933 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014934 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053014935 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014936#ifdef FEATURE_WLAN_TDLS
14937 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014938 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014939 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014940 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
14941 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014942 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014943 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014944 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014946 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014947 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014948 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014949 status = sme_DeleteTdlsPeerSta(
14950 WLAN_HDD_GET_HAL_CTX(pAdapter),
14951 pAdapter->sessionId,
14952 mac);
14953 if (status != eHAL_STATUS_SUCCESS) {
14954 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
14955 return -EPERM;
14956 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014957 }
14958 }
14959#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014960 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014961 status = wlan_hdd_disconnect(pAdapter, reasonCode);
14962 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070014963 {
14964 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014965 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014966 __func__, (int)status );
14967 return -EINVAL;
14968 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014969 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014970 else
14971 {
14972 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
14973 "called while in %d state", __func__,
14974 pHddStaCtx->conn_info.connState);
14975 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014976 }
14977 else
14978 {
14979 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
14980 }
14981
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014982 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014983 return status;
14984}
14985
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014986static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
14987 struct net_device *dev,
14988 u16 reason
14989 )
14990{
14991 int ret;
14992 vos_ssr_protect(__func__);
14993 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
14994 vos_ssr_unprotect(__func__);
14995
14996 return ret;
14997}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014998
Jeff Johnson295189b2012-06-20 16:38:30 -070014999/*
15000 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015001 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015002 * settings in IBSS mode.
15003 */
15004static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015005 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015006 struct cfg80211_ibss_params *params
15007 )
15008{
15009 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015010 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015011 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15012 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015013
Jeff Johnson295189b2012-06-20 16:38:30 -070015014 ENTER();
15015
15016 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070015017 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070015018
15019 if (params->ie_len && ( NULL != params->ie) )
15020 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015021 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15022 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015023 {
15024 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15025 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15026 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015027 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015028 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015029 tDot11fIEWPA dot11WPAIE;
15030 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015031 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015032
Wilson Yang00256342013-10-10 23:13:38 -070015033 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015034 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15035 params->ie_len, DOT11F_EID_WPA);
15036 if ( NULL != ie )
15037 {
15038 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15039 // Unpack the WPA IE
15040 //Skip past the EID byte and length byte - and four byte WiFi OUI
15041 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
15042 &ie[2+4],
15043 ie[1] - 4,
15044 &dot11WPAIE);
15045 /*Extract the multicast cipher, the encType for unicast
15046 cipher for wpa-none is none*/
15047 encryptionType =
15048 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
15049 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015050 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015051
Jeff Johnson295189b2012-06-20 16:38:30 -070015052 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
15053
15054 if (0 > status)
15055 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015056 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015057 __func__);
15058 return status;
15059 }
15060 }
15061
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015062 pWextState->roamProfile.AuthType.authType[0] =
15063 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070015064 eCSR_AUTH_TYPE_OPEN_SYSTEM;
15065
15066 if (params->privacy)
15067 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015068 /* Security enabled IBSS, At this time there is no information available
15069 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070015070 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015071 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070015072 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015073 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070015074 *enable privacy bit in beacons */
15075
15076 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
15077 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015078 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
15079 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070015080 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15081 pWextState->roamProfile.EncryptionType.numEntries = 1;
15082 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070015083 return status;
15084}
15085
15086/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015087 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015088 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015089 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015090static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015091 struct net_device *dev,
15092 struct cfg80211_ibss_params *params
15093 )
15094{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015095 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015096 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15097 tCsrRoamProfile *pRoamProfile;
15098 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015099 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15100 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015101 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070015102
15103 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015104
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015105 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15106 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
15107 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015108 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015109 "%s: device_mode = %s (%d)", __func__,
15110 hdd_device_modetoString(pAdapter->device_mode),
15111 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015112
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015113 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015114 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015115 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015116 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015117 }
15118
15119 if (NULL == pWextState)
15120 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015121 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015122 __func__);
15123 return -EIO;
15124 }
15125
Agarwal Ashish51325b52014-06-16 16:50:49 +053015126 if (vos_max_concurrent_connections_reached()) {
15127 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15128 return -ECONNREFUSED;
15129 }
15130
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015131 /*Try disconnecting if already in connected state*/
15132 status = wlan_hdd_try_disconnect(pAdapter);
15133 if ( 0 > status)
15134 {
15135 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15136 " IBSS connection"));
15137 return -EALREADY;
15138 }
15139
Jeff Johnson295189b2012-06-20 16:38:30 -070015140 pRoamProfile = &pWextState->roamProfile;
15141
15142 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
15143 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015144 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015145 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015146 return -EINVAL;
15147 }
15148
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015149 /* BSSID is provided by upper layers hence no need to AUTO generate */
15150 if (NULL != params->bssid) {
15151 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15152 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
15153 hddLog (VOS_TRACE_LEVEL_ERROR,
15154 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15155 return -EIO;
15156 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015157 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015158 }
krunal sonie9002db2013-11-25 14:24:17 -080015159 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
15160 {
15161 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15162 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
15163 {
15164 hddLog (VOS_TRACE_LEVEL_ERROR,
15165 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15166 return -EIO;
15167 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015168
15169 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080015170 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015171 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080015172 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015173
Jeff Johnson295189b2012-06-20 16:38:30 -070015174 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070015175 if (NULL !=
15176#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15177 params->chandef.chan)
15178#else
15179 params->channel)
15180#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015181 {
15182 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015183 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15184 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
15185 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15186 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015187
15188 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015189 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070015190 ieee80211_frequency_to_channel(
15191#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15192 params->chandef.chan->center_freq);
15193#else
15194 params->channel->center_freq);
15195#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015196
15197 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15198 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070015199 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015200 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
15201 __func__);
15202 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070015203 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015204
15205 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015206 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015207 if (channelNum == validChan[indx])
15208 {
15209 break;
15210 }
15211 }
15212 if (indx >= numChans)
15213 {
15214 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015215 __func__, channelNum);
15216 return -EINVAL;
15217 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015218 /* Set the Operational Channel */
15219 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
15220 channelNum);
15221 pRoamProfile->ChannelInfo.numOfChannels = 1;
15222 pHddStaCtx->conn_info.operationChannel = channelNum;
15223 pRoamProfile->ChannelInfo.ChannelList =
15224 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070015225 }
15226
15227 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015228 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070015229 if (status < 0)
15230 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015231 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070015232 __func__);
15233 return status;
15234 }
15235
15236 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015237 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053015238 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015239 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015240
15241 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015242 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015243
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015244 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015245 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015246}
15247
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015248static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
15249 struct net_device *dev,
15250 struct cfg80211_ibss_params *params
15251 )
15252{
15253 int ret = 0;
15254
15255 vos_ssr_protect(__func__);
15256 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15257 vos_ssr_unprotect(__func__);
15258
15259 return ret;
15260}
15261
Jeff Johnson295189b2012-06-20 16:38:30 -070015262/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015263 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015264 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015265 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015266static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015267 struct net_device *dev
15268 )
15269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015270 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015271 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15272 tCsrRoamProfile *pRoamProfile;
15273 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015274 int status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015275#ifdef WLAN_FEATURE_RMC
15276 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
15277#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015278
15279 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015280
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015281 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15282 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15283 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015284 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015285 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015286 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015287 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015288 }
15289
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015290 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15291 hdd_device_modetoString(pAdapter->device_mode),
15292 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015293 if (NULL == pWextState)
15294 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015295 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015296 __func__);
15297 return -EIO;
15298 }
15299
15300 pRoamProfile = &pWextState->roamProfile;
15301
15302 /* Issue disconnect only if interface type is set to IBSS */
15303 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15304 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015305 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015306 __func__);
15307 return -EINVAL;
15308 }
15309
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015310#ifdef WLAN_FEATURE_RMC
15311 /* Clearing add IE of beacon */
15312 if (ccmCfgSetStr(pHddCtx->hHal,
15313 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
15314 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
15315 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15316 {
15317 hddLog (VOS_TRACE_LEVEL_ERROR,
15318 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
15319 return -EINVAL;
15320 }
15321 if (ccmCfgSetInt(pHddCtx->hHal,
15322 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
15323 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15324 {
15325 hddLog (VOS_TRACE_LEVEL_ERROR,
15326 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
15327 __func__);
15328 return -EINVAL;
15329 }
15330
15331 // Reset WNI_CFG_PROBE_RSP Flags
15332 wlan_hdd_reset_prob_rspies(pAdapter);
15333
15334 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15335 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
15336 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15337 {
15338 hddLog (VOS_TRACE_LEVEL_ERROR,
15339 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
15340 __func__);
15341 return -EINVAL;
15342 }
15343#endif
15344
Jeff Johnson295189b2012-06-20 16:38:30 -070015345 /* Issue Disconnect request */
15346 INIT_COMPLETION(pAdapter->disconnect_comp_var);
15347 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15348 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15349
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015350 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015351 return 0;
15352}
15353
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015354static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15355 struct net_device *dev
15356 )
15357{
15358 int ret = 0;
15359
15360 vos_ssr_protect(__func__);
15361 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15362 vos_ssr_unprotect(__func__);
15363
15364 return ret;
15365}
15366
Jeff Johnson295189b2012-06-20 16:38:30 -070015367/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015368 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015369 * This function is used to set the phy parameters
15370 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15371 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015372static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015373 u32 changed)
15374{
15375 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15376 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015377 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015378
15379 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015380
15381 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015382 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15383 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015384
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015385 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015386 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015387 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015388 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015389 }
15390
Jeff Johnson295189b2012-06-20 16:38:30 -070015391 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15392 {
15393 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15394 WNI_CFG_RTS_THRESHOLD_STAMAX :
15395 wiphy->rts_threshold;
15396
15397 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015398 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015399 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015400 hddLog(VOS_TRACE_LEVEL_ERROR,
15401 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015402 __func__, rts_threshold);
15403 return -EINVAL;
15404 }
15405
15406 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15407 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015408 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015409 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015410 hddLog(VOS_TRACE_LEVEL_ERROR,
15411 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015412 __func__, rts_threshold);
15413 return -EIO;
15414 }
15415
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015416 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015417 rts_threshold);
15418 }
15419
15420 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15421 {
15422 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15423 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15424 wiphy->frag_threshold;
15425
15426 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015427 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015428 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015429 hddLog(VOS_TRACE_LEVEL_ERROR,
15430 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015431 frag_threshold);
15432 return -EINVAL;
15433 }
15434
15435 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15436 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015437 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015438 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015439 hddLog(VOS_TRACE_LEVEL_ERROR,
15440 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015441 __func__, frag_threshold);
15442 return -EIO;
15443 }
15444
15445 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15446 frag_threshold);
15447 }
15448
15449 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15450 || (changed & WIPHY_PARAM_RETRY_LONG))
15451 {
15452 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15453 wiphy->retry_short :
15454 wiphy->retry_long;
15455
15456 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15457 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15458 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015459 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015460 __func__, retry_value);
15461 return -EINVAL;
15462 }
15463
15464 if (changed & WIPHY_PARAM_RETRY_SHORT)
15465 {
15466 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15467 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015468 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015469 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015470 hddLog(VOS_TRACE_LEVEL_ERROR,
15471 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015472 __func__, retry_value);
15473 return -EIO;
15474 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015475 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015476 __func__, retry_value);
15477 }
15478 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15479 {
15480 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15481 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015482 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015483 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015484 hddLog(VOS_TRACE_LEVEL_ERROR,
15485 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015486 __func__, retry_value);
15487 return -EIO;
15488 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015489 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015490 __func__, retry_value);
15491 }
15492 }
15493
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015494 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015495 return 0;
15496}
15497
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015498static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15499 u32 changed)
15500{
15501 int ret;
15502
15503 vos_ssr_protect(__func__);
15504 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15505 vos_ssr_unprotect(__func__);
15506
15507 return ret;
15508}
15509
Jeff Johnson295189b2012-06-20 16:38:30 -070015510/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015511 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015512 * This function is used to set the txpower
15513 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015514static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015515#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15516 struct wireless_dev *wdev,
15517#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015518#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015519 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015520#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015521 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015522#endif
15523 int dbm)
15524{
15525 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015526 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015527 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15528 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015529 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015530
15531 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015532
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015533 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15534 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15535 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015536 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015537 if (0 != status)
15538 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015539 return status;
15540 }
15541
15542 hHal = pHddCtx->hHal;
15543
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015544 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15545 dbm, ccmCfgSetCallback,
15546 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015547 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015548 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015549 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15550 return -EIO;
15551 }
15552
15553 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15554 dbm);
15555
15556 switch(type)
15557 {
15558 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15559 /* Fall through */
15560 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15561 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15562 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015563 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15564 __func__);
15565 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015566 }
15567 break;
15568 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015569 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015570 __func__);
15571 return -EOPNOTSUPP;
15572 break;
15573 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015574 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15575 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015576 return -EIO;
15577 }
15578
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015579 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015580 return 0;
15581}
15582
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015583static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15584#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15585 struct wireless_dev *wdev,
15586#endif
15587#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15588 enum tx_power_setting type,
15589#else
15590 enum nl80211_tx_power_setting type,
15591#endif
15592 int dbm)
15593{
15594 int ret;
15595 vos_ssr_protect(__func__);
15596 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15597#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15598 wdev,
15599#endif
15600#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15601 type,
15602#else
15603 type,
15604#endif
15605 dbm);
15606 vos_ssr_unprotect(__func__);
15607
15608 return ret;
15609}
15610
Jeff Johnson295189b2012-06-20 16:38:30 -070015611/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015612 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015613 * This function is used to read the txpower
15614 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015615static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015616#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15617 struct wireless_dev *wdev,
15618#endif
15619 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015620{
15621
15622 hdd_adapter_t *pAdapter;
15623 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015624 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015625
Jeff Johnsone7245742012-09-05 17:12:55 -070015626 ENTER();
15627
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015628 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015629 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015630 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015631 *dbm = 0;
15632 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015633 }
15634
Jeff Johnson295189b2012-06-20 16:38:30 -070015635 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15636 if (NULL == pAdapter)
15637 {
15638 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15639 return -ENOENT;
15640 }
15641
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015642 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15643 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15644 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015645 wlan_hdd_get_classAstats(pAdapter);
15646 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15647
Jeff Johnsone7245742012-09-05 17:12:55 -070015648 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015649 return 0;
15650}
15651
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015652static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15653#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15654 struct wireless_dev *wdev,
15655#endif
15656 int *dbm)
15657{
15658 int ret;
15659
15660 vos_ssr_protect(__func__);
15661 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15662#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15663 wdev,
15664#endif
15665 dbm);
15666 vos_ssr_unprotect(__func__);
15667
15668 return ret;
15669}
15670
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015671static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015672#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15673 const u8* mac,
15674#else
15675 u8* mac,
15676#endif
15677 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015678{
15679 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15680 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15681 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053015682 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015683
15684 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
15685 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070015686
15687 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
15688 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
15689 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
15690 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
15691 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
15692 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
15693 tANI_U16 maxRate = 0;
15694 tANI_U16 myRate;
15695 tANI_U16 currentRate = 0;
15696 tANI_U8 maxSpeedMCS = 0;
15697 tANI_U8 maxMCSIdx = 0;
15698 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053015699 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070015700 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015701 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015702
Leo Chang6f8870f2013-03-26 18:11:36 -070015703#ifdef WLAN_FEATURE_11AC
15704 tANI_U32 vht_mcs_map;
15705 eDataRate11ACMaxMcs vhtMaxMcs;
15706#endif /* WLAN_FEATURE_11AC */
15707
Jeff Johnsone7245742012-09-05 17:12:55 -070015708 ENTER();
15709
Jeff Johnson295189b2012-06-20 16:38:30 -070015710 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15711 (0 == ssidlen))
15712 {
15713 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
15714 " Invalid ssidlen, %d", __func__, ssidlen);
15715 /*To keep GUI happy*/
15716 return 0;
15717 }
15718
Mukul Sharma811205f2014-07-09 21:07:30 +053015719 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
15720 {
15721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15722 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053015723 /* return a cached value */
15724 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053015725 return 0;
15726 }
15727
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015728 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015729 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015730 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015731 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015732 }
15733
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053015734 wlan_hdd_get_station_stats(pAdapter);
15735 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015736
Kiet Lam3b17fc82013-09-27 05:24:08 +053015737 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
15738 sinfo->filled |= STATION_INFO_SIGNAL;
15739
c_hpothu09f19542014-05-30 21:53:31 +053015740 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053015741 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
15742 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053015743 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053015744 {
15745 rate_flags = pAdapter->maxRateFlags;
15746 }
c_hpothu44ff4e02014-05-08 00:13:57 +053015747
Jeff Johnson295189b2012-06-20 16:38:30 -070015748 //convert to the UI units of 100kbps
15749 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
15750
15751#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070015752 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 -070015753 sinfo->signal,
15754 pCfg->reportMaxLinkSpeed,
15755 myRate,
15756 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015757 (int) pCfg->linkSpeedRssiMid,
15758 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070015759 (int) rate_flags,
15760 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070015761#endif //LINKSPEED_DEBUG_ENABLED
15762
15763 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
15764 {
15765 // we do not want to necessarily report the current speed
15766 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
15767 {
15768 // report the max possible speed
15769 rssidx = 0;
15770 }
15771 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
15772 {
15773 // report the max possible speed with RSSI scaling
15774 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
15775 {
15776 // report the max possible speed
15777 rssidx = 0;
15778 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015779 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070015780 {
15781 // report middle speed
15782 rssidx = 1;
15783 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015784 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
15785 {
15786 // report middle speed
15787 rssidx = 2;
15788 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015789 else
15790 {
15791 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015792 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070015793 }
15794 }
15795 else
15796 {
15797 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
15798 hddLog(VOS_TRACE_LEVEL_ERROR,
15799 "%s: Invalid value for reportMaxLinkSpeed: %u",
15800 __func__, pCfg->reportMaxLinkSpeed);
15801 rssidx = 0;
15802 }
15803
15804 maxRate = 0;
15805
15806 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015807 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
15808 OperationalRates, &ORLeng))
15809 {
15810 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15811 /*To keep GUI happy*/
15812 return 0;
15813 }
15814
Jeff Johnson295189b2012-06-20 16:38:30 -070015815 for (i = 0; i < ORLeng; i++)
15816 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015817 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015818 {
15819 /* Validate Rate Set */
15820 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
15821 {
15822 currentRate = supported_data_rate[j].supported_rate[rssidx];
15823 break;
15824 }
15825 }
15826 /* Update MAX rate */
15827 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15828 }
15829
15830 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015831 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
15832 ExtendedRates, &ERLeng))
15833 {
15834 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15835 /*To keep GUI happy*/
15836 return 0;
15837 }
15838
Jeff Johnson295189b2012-06-20 16:38:30 -070015839 for (i = 0; i < ERLeng; i++)
15840 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015841 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015842 {
15843 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
15844 {
15845 currentRate = supported_data_rate[j].supported_rate[rssidx];
15846 break;
15847 }
15848 }
15849 /* Update MAX rate */
15850 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15851 }
c_hpothu79aab322014-07-14 21:11:01 +053015852
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015853 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053015854 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015855 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053015856 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070015857 {
c_hpothu79aab322014-07-14 21:11:01 +053015858 if (rate_flags & eHAL_TX_RATE_VHT80)
15859 mode = 2;
15860 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
15861 mode = 1;
15862 else
15863 mode = 0;
15864
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015865 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
15866 MCSRates, &MCSLeng))
15867 {
15868 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15869 /*To keep GUI happy*/
15870 return 0;
15871 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015872 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070015873#ifdef WLAN_FEATURE_11AC
15874 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015875 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070015876 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015877 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015878 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070015879 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070015880 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015881 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015882 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015883 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070015884 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015885 maxMCSIdx = 7;
15886 }
15887 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
15888 {
15889 maxMCSIdx = 8;
15890 }
15891 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
15892 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015893 //VHT20 is supporting 0~8
15894 if (rate_flags & eHAL_TX_RATE_VHT20)
15895 maxMCSIdx = 8;
15896 else
15897 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070015898 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015899
c_hpothu79aab322014-07-14 21:11:01 +053015900 if (0 != rssidx)/*check for scaled */
15901 {
15902 //get middle rate MCS index if rssi=1/2
15903 for (i=0; i <= maxMCSIdx; i++)
15904 {
15905 if (sinfo->signal <= rssiMcsTbl[mode][i])
15906 {
15907 maxMCSIdx = i;
15908 break;
15909 }
15910 }
15911 }
15912
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015913 if (rate_flags & eHAL_TX_RATE_VHT80)
15914 {
15915 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
15916 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
15917 }
15918 else if (rate_flags & eHAL_TX_RATE_VHT40)
15919 {
15920 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
15921 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
15922 }
15923 else if (rate_flags & eHAL_TX_RATE_VHT20)
15924 {
15925 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
15926 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
15927 }
15928
Leo Chang6f8870f2013-03-26 18:11:36 -070015929 maxSpeedMCS = 1;
15930 if (currentRate > maxRate)
15931 {
15932 maxRate = currentRate;
15933 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015934
Leo Chang6f8870f2013-03-26 18:11:36 -070015935 }
15936 else
15937#endif /* WLAN_FEATURE_11AC */
15938 {
15939 if (rate_flags & eHAL_TX_RATE_HT40)
15940 {
15941 rateFlag |= 1;
15942 }
15943 if (rate_flags & eHAL_TX_RATE_SGI)
15944 {
15945 rateFlag |= 2;
15946 }
15947
Girish Gowli01abcee2014-07-31 20:18:55 +053015948 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053015949 if (rssidx == 1 || rssidx == 2)
15950 {
15951 //get middle rate MCS index if rssi=1/2
15952 for (i=0; i <= 7; i++)
15953 {
15954 if (sinfo->signal <= rssiMcsTbl[mode][i])
15955 {
15956 temp = i+1;
15957 break;
15958 }
15959 }
15960 }
c_hpothu79aab322014-07-14 21:11:01 +053015961
15962 for (i = 0; i < MCSLeng; i++)
15963 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015964 for (j = 0; j < temp; j++)
15965 {
15966 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
15967 {
15968 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015969 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015970 break;
15971 }
15972 }
15973 if ((j < temp) && (currentRate > maxRate))
15974 {
15975 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070015976 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015977 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015978 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015979 }
15980 }
15981
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015982 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
15983 {
15984 maxRate = myRate;
15985 maxSpeedMCS = 1;
15986 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15987 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015988 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053015989 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070015990 {
15991 maxRate = myRate;
15992 if (rate_flags & eHAL_TX_RATE_LEGACY)
15993 {
15994 maxSpeedMCS = 0;
15995 }
15996 else
15997 {
15998 maxSpeedMCS = 1;
15999 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16000 }
16001 }
16002
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016003 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070016004 {
16005 sinfo->txrate.legacy = maxRate;
16006#ifdef LINKSPEED_DEBUG_ENABLED
16007 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
16008#endif //LINKSPEED_DEBUG_ENABLED
16009 }
16010 else
16011 {
16012 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070016013#ifdef WLAN_FEATURE_11AC
16014 sinfo->txrate.nss = 1;
16015 if (rate_flags & eHAL_TX_RATE_VHT80)
16016 {
16017 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016018 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070016019 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016020 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070016021 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016022 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16023 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16024 }
16025 else if (rate_flags & eHAL_TX_RATE_VHT20)
16026 {
16027 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16028 }
16029#endif /* WLAN_FEATURE_11AC */
16030 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
16031 {
16032 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16033 if (rate_flags & eHAL_TX_RATE_HT40)
16034 {
16035 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16036 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016037 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016038 if (rate_flags & eHAL_TX_RATE_SGI)
16039 {
16040 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16041 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016042
Jeff Johnson295189b2012-06-20 16:38:30 -070016043#ifdef LINKSPEED_DEBUG_ENABLED
16044 pr_info("Reporting MCS rate %d flags %x\n",
16045 sinfo->txrate.mcs,
16046 sinfo->txrate.flags );
16047#endif //LINKSPEED_DEBUG_ENABLED
16048 }
16049 }
16050 else
16051 {
16052 // report current rate instead of max rate
16053
16054 if (rate_flags & eHAL_TX_RATE_LEGACY)
16055 {
16056 //provide to the UI in units of 100kbps
16057 sinfo->txrate.legacy = myRate;
16058#ifdef LINKSPEED_DEBUG_ENABLED
16059 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
16060#endif //LINKSPEED_DEBUG_ENABLED
16061 }
16062 else
16063 {
16064 //must be MCS
16065 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016066#ifdef WLAN_FEATURE_11AC
16067 sinfo->txrate.nss = 1;
16068 if (rate_flags & eHAL_TX_RATE_VHT80)
16069 {
16070 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16071 }
16072 else
16073#endif /* WLAN_FEATURE_11AC */
16074 {
16075 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16076 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016077 if (rate_flags & eHAL_TX_RATE_SGI)
16078 {
16079 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16080 }
16081 if (rate_flags & eHAL_TX_RATE_HT40)
16082 {
16083 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16084 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016085#ifdef WLAN_FEATURE_11AC
16086 else if (rate_flags & eHAL_TX_RATE_VHT80)
16087 {
16088 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
16089 }
16090#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070016091#ifdef LINKSPEED_DEBUG_ENABLED
16092 pr_info("Reporting actual MCS rate %d flags %x\n",
16093 sinfo->txrate.mcs,
16094 sinfo->txrate.flags );
16095#endif //LINKSPEED_DEBUG_ENABLED
16096 }
16097 }
16098 sinfo->filled |= STATION_INFO_TX_BITRATE;
16099
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016100 sinfo->tx_packets =
16101 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
16102 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
16103 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
16104 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
16105
16106 sinfo->tx_retries =
16107 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
16108 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
16109 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
16110 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
16111
16112 sinfo->tx_failed =
16113 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
16114 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
16115 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
16116 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
16117
16118 sinfo->filled |=
16119 STATION_INFO_TX_PACKETS |
16120 STATION_INFO_TX_RETRIES |
16121 STATION_INFO_TX_FAILED;
16122
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053016123 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
16124 sinfo->filled |= STATION_INFO_RX_PACKETS;
16125
16126 if (rate_flags & eHAL_TX_RATE_LEGACY)
16127 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
16128 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
16129 sinfo->rx_packets);
16130 else
16131 hddLog(LOG1,
16132 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
16133 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
16134 sinfo->tx_packets, sinfo->rx_packets);
16135
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016136 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16137 TRACE_CODE_HDD_CFG80211_GET_STA,
16138 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016139 EXIT();
16140 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016141}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016142#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16143static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16144 const u8* mac, struct station_info *sinfo)
16145#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016146static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16147 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016148#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016149{
16150 int ret;
16151
16152 vos_ssr_protect(__func__);
16153 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
16154 vos_ssr_unprotect(__func__);
16155
16156 return ret;
16157}
16158
16159static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070016160 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070016161{
16162 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016163 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016164 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016165 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016166
Jeff Johnsone7245742012-09-05 17:12:55 -070016167 ENTER();
16168
Jeff Johnson295189b2012-06-20 16:38:30 -070016169 if (NULL == pAdapter)
16170 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016171 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016172 return -ENODEV;
16173 }
16174
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016175 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16176 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
16177 pAdapter->sessionId, timeout));
16178
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016179 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016180 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016181 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016182 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016183 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016184 }
16185
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016186 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
16187 (TRUE == pHddCtx->hdd_wlan_suspended) &&
16188 (pHddCtx->cfg_ini->fhostArpOffload) &&
16189 (eConnectionState_Associated ==
16190 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
16191 {
Amar Singhald53568e2013-09-26 11:03:45 -070016192
16193 hddLog(VOS_TRACE_LEVEL_INFO,
16194 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053016195 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016196 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16197 {
16198 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016199 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016200 __func__, vos_status);
16201 }
16202 }
16203
Jeff Johnson295189b2012-06-20 16:38:30 -070016204 /**The get power cmd from the supplicant gets updated by the nl only
16205 *on successful execution of the function call
16206 *we are oppositely mapped w.r.t mode in the driver
16207 **/
16208 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
16209
16210 if (VOS_STATUS_E_FAILURE == vos_status)
16211 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16213 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016214 return -EINVAL;
16215 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016216 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016217 return 0;
16218}
16219
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016220static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
16221 struct net_device *dev, bool mode, int timeout)
16222{
16223 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016224
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016225 vos_ssr_protect(__func__);
16226 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
16227 vos_ssr_unprotect(__func__);
16228
16229 return ret;
16230}
Sushant Kaushik084f6592015-09-10 13:11:56 +053016231
Jeff Johnson295189b2012-06-20 16:38:30 -070016232#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016233static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
16234 struct net_device *netdev,
16235 u8 key_index)
16236{
16237 ENTER();
16238 return 0;
16239}
16240
Jeff Johnson295189b2012-06-20 16:38:30 -070016241static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016242 struct net_device *netdev,
16243 u8 key_index)
16244{
16245 int ret;
16246 vos_ssr_protect(__func__);
16247 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
16248 vos_ssr_unprotect(__func__);
16249 return ret;
16250}
16251#endif //LINUX_VERSION_CODE
16252
16253#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16254static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16255 struct net_device *dev,
16256 struct ieee80211_txq_params *params)
16257{
16258 ENTER();
16259 return 0;
16260}
16261#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16262static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16263 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016264{
Jeff Johnsone7245742012-09-05 17:12:55 -070016265 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070016266 return 0;
16267}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016268#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070016269
16270#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16271static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016272 struct net_device *dev,
16273 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016274{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016275 int ret;
16276
16277 vos_ssr_protect(__func__);
16278 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
16279 vos_ssr_unprotect(__func__);
16280 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016281}
16282#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16283static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
16284 struct ieee80211_txq_params *params)
16285{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016286 int ret;
16287
16288 vos_ssr_protect(__func__);
16289 ret = __wlan_hdd_set_txq_params(wiphy, params);
16290 vos_ssr_unprotect(__func__);
16291 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016292}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016293#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016294
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016295static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016296 struct net_device *dev,
16297 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070016298{
16299 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016300 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016301 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016302 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016303 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016304 v_CONTEXT_t pVosContext = NULL;
16305 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016306
Jeff Johnsone7245742012-09-05 17:12:55 -070016307 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016308
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016309 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016310 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016311 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016312 return -EINVAL;
16313 }
16314
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016315 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16316 TRACE_CODE_HDD_CFG80211_DEL_STA,
16317 pAdapter->sessionId, pAdapter->device_mode));
16318
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016319 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16320 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016321 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016322 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016323 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016324 }
16325
Jeff Johnson295189b2012-06-20 16:38:30 -070016326 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016327 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016328 )
16329 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016330 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16331 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16332 if(pSapCtx == NULL){
16333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16334 FL("psapCtx is NULL"));
16335 return -ENOENT;
16336 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016337 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016338 {
16339 v_U16_t i;
16340 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16341 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016342 if ((pSapCtx->aStaInfo[i].isUsed) &&
16343 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016344 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016345 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016346 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016347 ETHER_ADDR_LEN);
16348
Jeff Johnson295189b2012-06-20 16:38:30 -070016349 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016350 "%s: Delete STA with MAC::"
16351 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016352 __func__,
16353 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16354 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016355 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016356 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016357 }
16358 }
16359 }
16360 else
16361 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016362
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016363 vos_status = hdd_softap_GetStaId(pAdapter,
16364 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016365 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16366 {
16367 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016368 "%s: Skip this DEL STA as this is not used::"
16369 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016370 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016371 return -ENOENT;
16372 }
16373
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016374 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016375 {
16376 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016377 "%s: Skip this DEL STA as deauth is in progress::"
16378 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016379 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016380 return -ENOENT;
16381 }
16382
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016383 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016384
Jeff Johnson295189b2012-06-20 16:38:30 -070016385 hddLog(VOS_TRACE_LEVEL_INFO,
16386 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016387 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016388 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016389 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016390
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016391 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016392 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16393 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016394 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016395 hddLog(VOS_TRACE_LEVEL_INFO,
16396 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016397 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016398 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016399 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016400 return -ENOENT;
16401 }
16402
Jeff Johnson295189b2012-06-20 16:38:30 -070016403 }
16404 }
16405
16406 EXIT();
16407
16408 return 0;
16409}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016410
16411#ifdef CFG80211_DEL_STA_V2
16412static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16413 struct net_device *dev,
16414 struct station_del_parameters *param)
16415#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016416#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16417static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16418 struct net_device *dev, const u8 *mac)
16419#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016420static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16421 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016422#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016423#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016424{
16425 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016426 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016427
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016428 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016429
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016430#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016431 if (NULL == param) {
16432 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016433 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016434 return -EINVAL;
16435 }
16436
16437 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16438 param->subtype, &delStaParams);
16439
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016440#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016441 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016442 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016443#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016444 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16445
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016446 vos_ssr_unprotect(__func__);
16447
16448 return ret;
16449}
16450
16451static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016452 struct net_device *dev,
16453#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16454 const u8 *mac,
16455#else
16456 u8 *mac,
16457#endif
16458 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016459{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016460 hdd_adapter_t *pAdapter;
16461 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016462 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016463#ifdef FEATURE_WLAN_TDLS
16464 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016465
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016466 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016467
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016468 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16469 if (NULL == pAdapter)
16470 {
16471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16472 "%s: Adapter is NULL",__func__);
16473 return -EINVAL;
16474 }
16475 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16476 status = wlan_hdd_validate_context(pHddCtx);
16477 if (0 != status)
16478 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016479 return status;
16480 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016481
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016482 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16483 TRACE_CODE_HDD_CFG80211_ADD_STA,
16484 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016485 mask = params->sta_flags_mask;
16486
16487 set = params->sta_flags_set;
16488
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016490 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16491 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016492
16493 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16494 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016495 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016496 }
16497 }
16498#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016499 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016500 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016501}
16502
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016503#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16504static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16505 struct net_device *dev, const u8 *mac,
16506 struct station_parameters *params)
16507#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016508static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16509 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016510#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016511{
16512 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016513
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016514 vos_ssr_protect(__func__);
16515 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16516 vos_ssr_unprotect(__func__);
16517
16518 return ret;
16519}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016520#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016521
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016522static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016523 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016524{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016525 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16526 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016527 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016528 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016529 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016530 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016531
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016532 ENTER();
16533
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016534 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016535 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016536 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016537 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016538 return -EINVAL;
16539 }
16540
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016541 if (!pmksa) {
16542 hddLog(LOGE, FL("pmksa is NULL"));
16543 return -EINVAL;
16544 }
16545
16546 if (!pmksa->bssid || !pmksa->pmkid) {
16547 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16548 pmksa->bssid, pmksa->pmkid);
16549 return -EINVAL;
16550 }
16551
16552 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16553 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16554
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016555 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16556 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016557 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016558 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016559 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016560 }
16561
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016562 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016563 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16564
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016565 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16566 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016567
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016568 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016569 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016570 &pmk_id, 1, FALSE);
16571
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016572 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16573 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16574 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016575
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016576 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016577 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016578}
16579
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016580static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16581 struct cfg80211_pmksa *pmksa)
16582{
16583 int ret;
16584
16585 vos_ssr_protect(__func__);
16586 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16587 vos_ssr_unprotect(__func__);
16588
16589 return ret;
16590}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016591
Wilson Yang6507c4e2013-10-01 20:11:19 -070016592
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016593static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016594 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016595{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016596 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16597 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016598 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016599 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016600
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016601 ENTER();
16602
Wilson Yang6507c4e2013-10-01 20:11:19 -070016603 /* Validate pAdapter */
16604 if (NULL == pAdapter)
16605 {
16606 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16607 return -EINVAL;
16608 }
16609
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016610 if (!pmksa) {
16611 hddLog(LOGE, FL("pmksa is NULL"));
16612 return -EINVAL;
16613 }
16614
16615 if (!pmksa->bssid) {
16616 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16617 return -EINVAL;
16618 }
16619
Kiet Lam98c46a12014-10-31 15:34:57 -070016620 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16621 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16622
Wilson Yang6507c4e2013-10-01 20:11:19 -070016623 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16624 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016625 if (0 != status)
16626 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016627 return status;
16628 }
16629
16630 /*Retrieve halHandle*/
16631 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16632
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016633 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16634 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16635 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016636 /* Delete the PMKID CSR cache */
16637 if (eHAL_STATUS_SUCCESS !=
16638 sme_RoamDelPMKIDfromCache(halHandle,
16639 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16640 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16641 MAC_ADDR_ARRAY(pmksa->bssid));
16642 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016643 }
16644
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016645 EXIT();
16646 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016647}
16648
Wilson Yang6507c4e2013-10-01 20:11:19 -070016649
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016650static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16651 struct cfg80211_pmksa *pmksa)
16652{
16653 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016654
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016655 vos_ssr_protect(__func__);
16656 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16657 vos_ssr_unprotect(__func__);
16658
16659 return ret;
16660
16661}
16662
16663static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016664{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016665 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16666 tHalHandle halHandle;
16667 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016668 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016669
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016670 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016671
16672 /* Validate pAdapter */
16673 if (NULL == pAdapter)
16674 {
16675 hddLog(VOS_TRACE_LEVEL_ERROR,
16676 "%s: Invalid Adapter" ,__func__);
16677 return -EINVAL;
16678 }
16679
16680 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16681 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016682 if (0 != status)
16683 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016684 return status;
16685 }
16686
16687 /*Retrieve halHandle*/
16688 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16689
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016690 /* Flush the PMKID cache in CSR */
16691 if (eHAL_STATUS_SUCCESS !=
16692 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
16693 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
16694 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016695 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016696 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080016697 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016698}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016699
16700static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
16701{
16702 int ret;
16703
16704 vos_ssr_protect(__func__);
16705 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
16706 vos_ssr_unprotect(__func__);
16707
16708 return ret;
16709}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016710#endif
16711
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016712#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016713static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16714 struct net_device *dev,
16715 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016716{
16717 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16718 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016719 hdd_context_t *pHddCtx;
16720 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016721
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016722 ENTER();
16723
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016724 if (NULL == pAdapter)
16725 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016726 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016727 return -ENODEV;
16728 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016729 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16730 ret = wlan_hdd_validate_context(pHddCtx);
16731 if (0 != ret)
16732 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016733 return ret;
16734 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016735 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016736 if (NULL == pHddStaCtx)
16737 {
16738 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
16739 return -EINVAL;
16740 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016741
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016742 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16743 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
16744 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016745 // Added for debug on reception of Re-assoc Req.
16746 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
16747 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016748 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016749 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080016750 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016751 }
16752
16753#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080016754 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016755 ftie->ie_len);
16756#endif
16757
16758 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016759 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
16760 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016761 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016762
16763 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016764 return 0;
16765}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016766
16767static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16768 struct net_device *dev,
16769 struct cfg80211_update_ft_ies_params *ftie)
16770{
16771 int ret;
16772
16773 vos_ssr_protect(__func__);
16774 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
16775 vos_ssr_unprotect(__func__);
16776
16777 return ret;
16778}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016779#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016780
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016781#ifdef FEATURE_WLAN_SCAN_PNO
16782
16783void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
16784 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
16785{
16786 int ret;
16787 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
16788 hdd_context_t *pHddCtx;
16789
Nirav Shah80830bf2013-12-31 16:35:12 +053016790 ENTER();
16791
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016792 if (NULL == pAdapter)
16793 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016795 "%s: HDD adapter is Null", __func__);
16796 return ;
16797 }
16798
16799 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16800 if (NULL == pHddCtx)
16801 {
16802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16803 "%s: HDD context is Null!!!", __func__);
16804 return ;
16805 }
16806
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016807 spin_lock(&pHddCtx->schedScan_lock);
16808 if (TRUE == pHddCtx->isWiphySuspended)
16809 {
16810 pHddCtx->isSchedScanUpdatePending = TRUE;
16811 spin_unlock(&pHddCtx->schedScan_lock);
16812 hddLog(VOS_TRACE_LEVEL_INFO,
16813 "%s: Update cfg80211 scan database after it resume", __func__);
16814 return ;
16815 }
16816 spin_unlock(&pHddCtx->schedScan_lock);
16817
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016818 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
16819
16820 if (0 > ret)
16821 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053016822 else
16823 {
16824 /* Acquire wakelock to handle the case where APP's tries to suspend
16825 * immediatly after the driver gets connect request(i.e after pno)
16826 * from supplicant, this result in app's is suspending and not able
16827 * to process the connect request to AP */
16828 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
16829 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016830 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016831 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16832 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016833}
16834
16835/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016836 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016837 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016838 */
16839static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
16840{
16841 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16842 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016843 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016844 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16845 int status = 0;
16846 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
16847
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016848 /* The current firmware design does not allow PNO during any
16849 * active sessions. Hence, determine the active sessions
16850 * and return a failure.
16851 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016852 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
16853 {
16854 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016855 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016856
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016857 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
16858 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
16859 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
16860 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
16861 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053016862 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016863 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016864 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016865 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016866 }
16867 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16868 pAdapterNode = pNext;
16869 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016870 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016871}
16872
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016873void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
16874{
16875 hdd_adapter_t *pAdapter = callbackContext;
16876 hdd_context_t *pHddCtx;
16877
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016878 ENTER();
16879
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016880 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
16881 {
16882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16883 FL("Invalid adapter or adapter has invalid magic"));
16884 return;
16885 }
16886
16887 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16888 if (0 != wlan_hdd_validate_context(pHddCtx))
16889 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016890 return;
16891 }
16892
c_hpothub53c45d2014-08-18 16:53:14 +053016893 if (VOS_STATUS_SUCCESS != status)
16894 {
16895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016896 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053016897 pHddCtx->isPnoEnable = FALSE;
16898 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016899
16900 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
16901 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016902 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016903}
16904
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016905/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016906 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
16907 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016908 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016909static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016910 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16911{
16912 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016913 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016914 hdd_context_t *pHddCtx;
16915 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016916 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053016917 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
16918 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016919 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16920 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016921 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016922 hdd_config_t *pConfig = NULL;
16923 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016924
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016925 ENTER();
16926
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016927 if (NULL == pAdapter)
16928 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016930 "%s: HDD adapter is Null", __func__);
16931 return -ENODEV;
16932 }
16933
16934 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016935 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016936
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016937 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016938 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016939 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016940 }
16941
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016942 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016943 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16944 if (NULL == hHal)
16945 {
16946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16947 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016948 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016949 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016950 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16951 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
16952 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053016953 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016954 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053016955 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016956 {
16957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16958 "%s: aborting the existing scan is unsuccessfull", __func__);
16959 return -EBUSY;
16960 }
16961
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016962 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016963 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016964 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016965 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016966 return -EBUSY;
16967 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016968
c_hpothu37f21312014-04-09 21:49:54 +053016969 if (TRUE == pHddCtx->isPnoEnable)
16970 {
16971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16972 FL("already PNO is enabled"));
16973 return -EBUSY;
16974 }
c_hpothu225aa7c2014-10-22 17:45:13 +053016975
16976 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
16977 {
16978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16979 "%s: abort ROC failed ", __func__);
16980 return -EBUSY;
16981 }
16982
c_hpothu37f21312014-04-09 21:49:54 +053016983 pHddCtx->isPnoEnable = TRUE;
16984
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016985 pnoRequest.enable = 1; /*Enable PNO */
16986 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016987
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016988 if (( !pnoRequest.ucNetworksCount ) ||
16989 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016990 {
16991 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016992 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016993 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016994 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016995 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016996 goto error;
16997 }
16998
16999 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
17000 {
17001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017002 "%s: Incorrect number of channels %d",
17003 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017004 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017005 goto error;
17006 }
17007
17008 /* Framework provides one set of channels(all)
17009 * common for all saved profile */
17010 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17011 channels_allowed, &num_channels_allowed))
17012 {
17013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17014 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017015 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017016 goto error;
17017 }
17018 /* Checking each channel against allowed channel list */
17019 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053017020 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017021 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017022 char chList [(request->n_channels*5)+1];
17023 int len;
17024 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017025 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017026 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017027 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017028 if (request->channels[i]->hw_value == channels_allowed[indx])
17029 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017030 if ((!pConfig->enableDFSPnoChnlScan) &&
17031 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
17032 {
17033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17034 "%s : Dropping DFS channel : %d",
17035 __func__,channels_allowed[indx]);
17036 num_ignore_dfs_ch++;
17037 break;
17038 }
17039
Nirav Shah80830bf2013-12-31 16:35:12 +053017040 valid_ch[num_ch++] = request->channels[i]->hw_value;
17041 len += snprintf(chList+len, 5, "%d ",
17042 request->channels[i]->hw_value);
17043 break ;
17044 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017045 }
17046 }
Nirav Shah80830bf2013-12-31 16:35:12 +053017047 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017048
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017049 /*If all channels are DFS and dropped, then ignore the PNO request*/
17050 if (num_ignore_dfs_ch == request->n_channels)
17051 {
17052 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17053 "%s : All requested channels are DFS channels", __func__);
17054 ret = -EINVAL;
17055 goto error;
17056 }
17057 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017058
17059 pnoRequest.aNetworks =
17060 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17061 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017062 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017063 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17064 FL("failed to allocate memory aNetworks %u"),
17065 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17066 goto error;
17067 }
17068 vos_mem_zero(pnoRequest.aNetworks,
17069 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17070
17071 /* Filling per profile params */
17072 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
17073 {
17074 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017075 request->match_sets[i].ssid.ssid_len;
17076
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017077 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
17078 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017079 {
17080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017081 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017082 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017083 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017084 goto error;
17085 }
17086
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017087 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017088 request->match_sets[i].ssid.ssid,
17089 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17091 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017092 i, pnoRequest.aNetworks[i].ssId.ssId);
17093 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
17094 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
17095 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017096
17097 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017098 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
17099 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017100
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017101 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017102 }
17103
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017104 for (i = 0; i < request->n_ssids; i++)
17105 {
17106 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017107 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017108 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017109 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017110 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017111 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017112 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017113 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017114 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017115 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017116 break;
17117 }
17118 j++;
17119 }
17120 }
17121 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17122 "Number of hidden networks being Configured = %d",
17123 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080017125 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017126
17127 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17128 if (pnoRequest.p24GProbeTemplate == NULL)
17129 {
17130 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17131 FL("failed to allocate memory p24GProbeTemplate %u"),
17132 SIR_PNO_MAX_PB_REQ_SIZE);
17133 goto error;
17134 }
17135
17136 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17137 if (pnoRequest.p5GProbeTemplate == NULL)
17138 {
17139 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17140 FL("failed to allocate memory p5GProbeTemplate %u"),
17141 SIR_PNO_MAX_PB_REQ_SIZE);
17142 goto error;
17143 }
17144
17145 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17146 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17147
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053017148 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
17149 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017150 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017151 pnoRequest.us24GProbeTemplateLen = request->ie_len;
17152 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
17153 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017154
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017155 pnoRequest.us5GProbeTemplateLen = request->ie_len;
17156 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
17157 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017158 }
17159
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017160 /* Driver gets only one time interval which is hardcoded in
17161 * supplicant for 10000ms. Taking power consumption into account 6 timers
17162 * will be used, Timervalue is increased exponentially i.e 10,20,40,
17163 * 80,160,320 secs. And number of scan cycle for each timer
17164 * is configurable through INI param gPNOScanTimerRepeatValue.
17165 * If it is set to 0 only one timer will be used and PNO scan cycle
17166 * will be repeated after each interval specified by supplicant
17167 * till PNO is disabled.
17168 */
17169 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017170 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017171 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017172 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017173 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
17174
17175 tempInterval = (request->interval)/1000;
17176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17177 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
17178 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017179 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017180 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017181 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017182 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017183 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017184 tempInterval *= 2;
17185 }
17186 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017187 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017188
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017189 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017190
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017191 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017192 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17193 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017194 pAdapter->pno_req_status = 0;
17195
Nirav Shah80830bf2013-12-31 16:35:12 +053017196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17197 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017198 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
17199 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053017200
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017201 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017202 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017203 hdd_cfg80211_sched_scan_done_callback, pAdapter);
17204 if (eHAL_STATUS_SUCCESS != status)
17205 {
17206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017207 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017208 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017209 goto error;
17210 }
17211
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017212 ret = wait_for_completion_timeout(
17213 &pAdapter->pno_comp_var,
17214 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17215 if (0 >= ret)
17216 {
17217 // Did not receive the response for PNO enable in time.
17218 // Assuming the PNO enable was success.
17219 // Returning error from here, because we timeout, results
17220 // in side effect of Wifi (Wifi Setting) not to work.
17221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17222 FL("Timed out waiting for PNO to be Enabled"));
17223 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017224 }
17225
17226 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053017227 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017228
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017229error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17231 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053017232 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017233 if (pnoRequest.aNetworks)
17234 vos_mem_free(pnoRequest.aNetworks);
17235 if (pnoRequest.p24GProbeTemplate)
17236 vos_mem_free(pnoRequest.p24GProbeTemplate);
17237 if (pnoRequest.p5GProbeTemplate)
17238 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017239
17240 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017241 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017242}
17243
17244/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017245 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
17246 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017247 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017248static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
17249 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17250{
17251 int ret;
17252
17253 vos_ssr_protect(__func__);
17254 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
17255 vos_ssr_unprotect(__func__);
17256
17257 return ret;
17258}
17259
17260/*
17261 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
17262 * Function to disable PNO
17263 */
17264static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017265 struct net_device *dev)
17266{
17267 eHalStatus status = eHAL_STATUS_FAILURE;
17268 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17269 hdd_context_t *pHddCtx;
17270 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017271 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017272 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017273
17274 ENTER();
17275
17276 if (NULL == pAdapter)
17277 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017279 "%s: HDD adapter is Null", __func__);
17280 return -ENODEV;
17281 }
17282
17283 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017284
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017285 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017286 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017288 "%s: HDD context is Null", __func__);
17289 return -ENODEV;
17290 }
17291
17292 /* The return 0 is intentional when isLogpInProgress and
17293 * isLoadUnloadInProgress. We did observe a crash due to a return of
17294 * failure in sched_scan_stop , especially for a case where the unload
17295 * of the happens at the same time. The function __cfg80211_stop_sched_scan
17296 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
17297 * success. If it returns a failure , then its next invocation due to the
17298 * clean up of the second interface will have the dev pointer corresponding
17299 * to the first one leading to a crash.
17300 */
17301 if (pHddCtx->isLogpInProgress)
17302 {
17303 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17304 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017305 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017306 return ret;
17307 }
17308
Mihir Shete18156292014-03-11 15:38:30 +053017309 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017310 {
17311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17312 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17313 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017314 }
17315
17316 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17317 if (NULL == hHal)
17318 {
17319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17320 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017321 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017322 }
17323
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017324 pnoRequest.enable = 0; /* Disable PNO */
17325 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017326
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017327 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17328 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17329 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017330
17331 INIT_COMPLETION(pAdapter->pno_comp_var);
17332 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17333 pnoRequest.callbackContext = pAdapter;
17334 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017335 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017336 pAdapter->sessionId,
17337 NULL, pAdapter);
17338 if (eHAL_STATUS_SUCCESS != status)
17339 {
17340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17341 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017342 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017343 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017344 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017345 ret = wait_for_completion_timeout(
17346 &pAdapter->pno_comp_var,
17347 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17348 if (0 >= ret)
17349 {
17350 // Did not receive the response for PNO disable in time.
17351 // Assuming the PNO disable was success.
17352 // Returning error from here, because we timeout, results
17353 // in side effect of Wifi (Wifi Setting) not to work.
17354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17355 FL("Timed out waiting for PNO to be disabled"));
17356 ret = 0;
17357 }
17358
17359 ret = pAdapter->pno_req_status;
17360 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017361
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017362error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017364 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017365
17366 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017367 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017368}
17369
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017370/*
17371 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17372 * NL interface to disable PNO
17373 */
17374static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17375 struct net_device *dev)
17376{
17377 int ret;
17378
17379 vos_ssr_protect(__func__);
17380 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17381 vos_ssr_unprotect(__func__);
17382
17383 return ret;
17384}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017385#endif /*FEATURE_WLAN_SCAN_PNO*/
17386
17387
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017388#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017389#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017390static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17391 struct net_device *dev,
17392 u8 *peer, u8 action_code,
17393 u8 dialog_token,
17394 u16 status_code, u32 peer_capability,
17395 const u8 *buf, size_t len)
17396#else /* TDLS_MGMT_VERSION2 */
17397#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17398static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17399 struct net_device *dev,
17400 const u8 *peer, u8 action_code,
17401 u8 dialog_token, u16 status_code,
17402 u32 peer_capability, bool initiator,
17403 const u8 *buf, size_t len)
17404#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17405static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17406 struct net_device *dev,
17407 const u8 *peer, u8 action_code,
17408 u8 dialog_token, u16 status_code,
17409 u32 peer_capability, const u8 *buf,
17410 size_t len)
17411#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17412static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17413 struct net_device *dev,
17414 u8 *peer, u8 action_code,
17415 u8 dialog_token,
17416 u16 status_code, u32 peer_capability,
17417 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017418#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017419static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17420 struct net_device *dev,
17421 u8 *peer, u8 action_code,
17422 u8 dialog_token,
17423 u16 status_code, const u8 *buf,
17424 size_t len)
17425#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017426#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017427{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017428 hdd_adapter_t *pAdapter;
17429 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017430 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017431 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017432 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017433 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017434 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017435 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017436#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017437 u32 peer_capability = 0;
17438#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017439 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017440 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017441
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017442 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17443 if (NULL == pAdapter)
17444 {
17445 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17446 "%s: Adapter is NULL",__func__);
17447 return -EINVAL;
17448 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017449 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17450 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17451 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017452
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017453 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017454 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017455 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017457 "Invalid arguments");
17458 return -EINVAL;
17459 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017460
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017461 if (pHddCtx->isLogpInProgress)
17462 {
17463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17464 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017465 wlan_hdd_tdls_set_link_status(pAdapter,
17466 peer,
17467 eTDLS_LINK_IDLE,
17468 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017469 return -EBUSY;
17470 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017471
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017472 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17473 {
17474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17475 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17476 return -EAGAIN;
17477 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017478
Hoonki Lee27511902013-03-14 18:19:06 -070017479 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017480 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017482 "%s: TDLS mode is disabled OR not enabled in FW."
17483 MAC_ADDRESS_STR " action %d declined.",
17484 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017485 return -ENOTSUPP;
17486 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017487
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017488 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17489
17490 if( NULL == pHddStaCtx )
17491 {
17492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17493 "%s: HDD station context NULL ",__func__);
17494 return -EINVAL;
17495 }
17496
17497 /* STA should be connected and authenticated
17498 * before sending any TDLS frames
17499 */
17500 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17501 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17502 {
17503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17504 "STA is not connected or unauthenticated. "
17505 "connState %u, uIsAuthenticated %u",
17506 pHddStaCtx->conn_info.connState,
17507 pHddStaCtx->conn_info.uIsAuthenticated);
17508 return -EAGAIN;
17509 }
17510
Hoonki Lee27511902013-03-14 18:19:06 -070017511 /* other than teardown frame, other mgmt frames are not sent if disabled */
17512 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17513 {
17514 /* if tdls_mode is disabled to respond to peer's request */
17515 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17516 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017518 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017519 " TDLS mode is disabled. action %d declined.",
17520 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017521
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017522 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017523 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017524
17525 if (vos_max_concurrent_connections_reached())
17526 {
17527 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17528 return -EINVAL;
17529 }
Hoonki Lee27511902013-03-14 18:19:06 -070017530 }
17531
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017532 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17533 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017534 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017535 {
17536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017537 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017538 " TDLS setup is ongoing. action %d declined.",
17539 __func__, MAC_ADDR_ARRAY(peer), action_code);
17540 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017541 }
17542 }
17543
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017544 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17545 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017546 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017547 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17548 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017549 {
17550 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17551 we return error code at 'add_station()'. Hence we have this
17552 check again in addtion to add_station().
17553 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017554 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017555 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17557 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017558 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
17559 __func__, MAC_ADDR_ARRAY(peer), action_code,
17560 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053017561 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080017562 }
17563 else
17564 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017565 /* maximum reached. tweak to send error code to peer and return
17566 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017567 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17569 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017570 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
17571 __func__, MAC_ADDR_ARRAY(peer), status_code,
17572 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070017573 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017574 /* fall through to send setup resp with failure status
17575 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017576 }
17577 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017578 else
17579 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017580 mutex_lock(&pHddCtx->tdls_lock);
17581 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017582 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017583 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017584 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017586 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17587 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017588 return -EPERM;
17589 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017590 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017591 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017592 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017593
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017595 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017596 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17597 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017598
Hoonki Leea34dd892013-02-05 22:56:02 -080017599 /*Except teardown responder will not be used so just make 0*/
17600 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017601 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017602 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017603
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017604 mutex_lock(&pHddCtx->tdls_lock);
17605 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017606
17607 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17608 responder = pTdlsPeer->is_responder;
17609 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017610 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017612 "%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 -070017613 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17614 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017615 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017616 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017617 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017618 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017619 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017620
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017621 /* Discard TDLS setup if peer is removed by user app */
17622 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
17623 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17624 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
17625 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
17626
17627 mutex_lock(&pHddCtx->tdls_lock);
17628 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17629 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
17630 mutex_unlock(&pHddCtx->tdls_lock);
17631 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
17632 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
17633 MAC_ADDR_ARRAY(peer), action_code);
17634 return -EINVAL;
17635 }
17636 mutex_unlock(&pHddCtx->tdls_lock);
17637 }
17638
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017639 /* For explicit trigger of DIS_REQ come out of BMPS for
17640 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017641 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053017642 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017643 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17644 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070017645 {
17646 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
17647 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017649 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017650 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
17651 if (status != VOS_STATUS_SUCCESS) {
17652 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
17653 }
Hoonki Lee14621352013-04-16 17:51:19 -070017654 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017655 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017656 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
17658 }
17659 }
Hoonki Lee14621352013-04-16 17:51:19 -070017660 }
17661
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017662 /* make sure doesn't call send_mgmt() while it is pending */
17663 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
17664 {
17665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017666 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017667 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017668 ret = -EBUSY;
17669 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017670 }
17671
17672 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017673 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
17674
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017675 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
17676 pAdapter->sessionId, peer, action_code, dialog_token,
17677 status_code, peer_capability, (tANI_U8 *)buf, len,
17678 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017679
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017680 if (VOS_STATUS_SUCCESS != status)
17681 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17683 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017684 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017685 ret = -EINVAL;
17686 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017687 }
17688
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17690 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
17691 WAIT_TIME_TDLS_MGMT);
17692
Hoonki Leed37cbb32013-04-20 00:31:14 -070017693 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
17694 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
17695
17696 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017697 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070017698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070017699 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070017700 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017701 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080017702
17703 if (pHddCtx->isLogpInProgress)
17704 {
17705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17706 "%s: LOGP in Progress. Ignore!!!", __func__);
17707 return -EAGAIN;
17708 }
Abhishek Singh837adf22015-10-01 17:37:37 +053017709 if (rc <= 0)
17710 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
17711 WLAN_LOG_INDICATOR_HOST_DRIVER,
17712 WLAN_LOG_REASON_HDD_TIME_OUT,
17713 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080017714
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017715 ret = -EINVAL;
17716 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017717 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017718 else
17719 {
17720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17721 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
17722 __func__, rc, pAdapter->mgmtTxCompletionStatus);
17723 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017724
Gopichand Nakkala05922802013-03-14 12:23:19 -070017725 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070017726 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017727 ret = max_sta_failed;
17728 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070017729 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017730
Hoonki Leea34dd892013-02-05 22:56:02 -080017731 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
17732 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017733 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017734 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17735 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017736 }
17737 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
17738 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017739 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017740 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17741 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017742 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017743
17744 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017745
17746tx_failed:
17747 /* add_station will be called before sending TDLS_SETUP_REQ and
17748 * TDLS_SETUP_RSP and as part of add_station driver will enable
17749 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
17750 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
17751 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
17752 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
17753 */
17754
17755 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17756 (SIR_MAC_TDLS_SETUP_RSP == action_code))
17757 wlan_hdd_tdls_check_bmps(pAdapter);
17758 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017759}
17760
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017761#if TDLS_MGMT_VERSION2
17762static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17763 u8 *peer, u8 action_code, u8 dialog_token,
17764 u16 status_code, u32 peer_capability,
17765 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017766#else /* TDLS_MGMT_VERSION2 */
17767#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17768static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17769 struct net_device *dev,
17770 const u8 *peer, u8 action_code,
17771 u8 dialog_token, u16 status_code,
17772 u32 peer_capability, bool initiator,
17773 const u8 *buf, size_t len)
17774#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17775static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17776 struct net_device *dev,
17777 const u8 *peer, u8 action_code,
17778 u8 dialog_token, u16 status_code,
17779 u32 peer_capability, const u8 *buf,
17780 size_t len)
17781#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17782static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17783 struct net_device *dev,
17784 u8 *peer, u8 action_code,
17785 u8 dialog_token,
17786 u16 status_code, u32 peer_capability,
17787 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017788#else
17789static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17790 u8 *peer, u8 action_code, u8 dialog_token,
17791 u16 status_code, const u8 *buf, size_t len)
17792#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017793#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017794{
17795 int ret;
17796
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017797 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017798#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017799 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17800 dialog_token, status_code,
17801 peer_capability, buf, len);
17802#else /* TDLS_MGMT_VERSION2 */
17803#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17804 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17805 dialog_token, status_code,
17806 peer_capability, initiator,
17807 buf, len);
17808#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17809 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17810 dialog_token, status_code,
17811 peer_capability, buf, len);
17812#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17813 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17814 dialog_token, status_code,
17815 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017816#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017817 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17818 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017819#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017820#endif
17821 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017822
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017823 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017824}
Atul Mittal115287b2014-07-08 13:26:33 +053017825
17826int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017827#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17828 const u8 *peer,
17829#else
Atul Mittal115287b2014-07-08 13:26:33 +053017830 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017831#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017832 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053017833 cfg80211_exttdls_callback callback)
17834{
17835
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017836 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053017837 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017838 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053017839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17840 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
17841 __func__, MAC_ADDR_ARRAY(peer));
17842
17843 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17844 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17845
17846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017847 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17848 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17849 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017850 return -ENOTSUPP;
17851 }
17852
17853 /* To cater the requirement of establishing the TDLS link
17854 * irrespective of the data traffic , get an entry of TDLS peer.
17855 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017856 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017857 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
17858 if (pTdlsPeer == NULL) {
17859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17860 "%s: peer " MAC_ADDRESS_STR " not existing",
17861 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017862 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017863 return -EINVAL;
17864 }
17865
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017866 /* check FW TDLS Off Channel capability */
17867 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017868 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017869 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017870 {
17871 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
17872 pTdlsPeer->peerParams.global_operating_class =
17873 tdls_peer_params->global_operating_class;
17874 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
17875 pTdlsPeer->peerParams.min_bandwidth_kbps =
17876 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017877 /* check configured channel is valid, non dfs and
17878 * not current operating channel */
17879 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
17880 tdls_peer_params->channel)) &&
17881 (pHddStaCtx) &&
17882 (tdls_peer_params->channel !=
17883 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017884 {
17885 pTdlsPeer->isOffChannelConfigured = TRUE;
17886 }
17887 else
17888 {
17889 pTdlsPeer->isOffChannelConfigured = FALSE;
17890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17891 "%s: Configured Tdls Off Channel is not valid", __func__);
17892
17893 }
17894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017895 "%s: tdls_off_channel %d isOffChannelConfigured %d "
17896 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017897 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017898 pTdlsPeer->isOffChannelConfigured,
17899 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017900 }
17901 else
17902 {
17903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017904 "%s: TDLS off channel FW capability %d, "
17905 "host capab %d or Invalid TDLS Peer Params", __func__,
17906 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
17907 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017908 }
17909
Atul Mittal115287b2014-07-08 13:26:33 +053017910 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
17911
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017912 mutex_unlock(&pHddCtx->tdls_lock);
17913
Atul Mittal115287b2014-07-08 13:26:33 +053017914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17915 " %s TDLS Add Force Peer Failed",
17916 __func__);
17917 return -EINVAL;
17918 }
17919 /*EXT TDLS*/
17920
17921 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017922 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17924 " %s TDLS set callback Failed",
17925 __func__);
17926 return -EINVAL;
17927 }
17928
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017929 mutex_unlock(&pHddCtx->tdls_lock);
17930
Atul Mittal115287b2014-07-08 13:26:33 +053017931 return(0);
17932
17933}
17934
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017935int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
17936#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17937 const u8 *peer
17938#else
17939 u8 *peer
17940#endif
17941)
Atul Mittal115287b2014-07-08 13:26:33 +053017942{
17943
17944 hddTdlsPeer_t *pTdlsPeer;
17945 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053017946
Atul Mittal115287b2014-07-08 13:26:33 +053017947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17948 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
17949 __func__, MAC_ADDR_ARRAY(peer));
17950
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017951 if (0 != wlan_hdd_validate_context(pHddCtx)) {
17952 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
17953 return -EINVAL;
17954 }
17955
Atul Mittal115287b2014-07-08 13:26:33 +053017956 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17957 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17958
17959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017960 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17961 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17962 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017963 return -ENOTSUPP;
17964 }
17965
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017966 mutex_lock(&pHddCtx->tdls_lock);
17967 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053017968
17969 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017970 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017971 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017972 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053017973 __func__, MAC_ADDR_ARRAY(peer));
17974 return -EINVAL;
17975 }
17976 else {
17977 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
17978 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053017979 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
17980 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017981 /* if channel switch is configured, reset
17982 the channel for this peer */
17983 if (TRUE == pTdlsPeer->isOffChannelConfigured)
17984 {
17985 pTdlsPeer->peerParams.channel = 0;
17986 pTdlsPeer->isOffChannelConfigured = FALSE;
17987 }
Atul Mittal115287b2014-07-08 13:26:33 +053017988 }
17989
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017990 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017991 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053017993 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017994 }
Atul Mittal115287b2014-07-08 13:26:33 +053017995
17996 /*EXT TDLS*/
17997
17998 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017999 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18001 " %s TDLS set callback Failed",
18002 __func__);
18003 return -EINVAL;
18004 }
Atul Mittal115287b2014-07-08 13:26:33 +053018005
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018006 mutex_unlock(&pHddCtx->tdls_lock);
18007
18008 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053018009}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018010static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018011#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18012 const u8 *peer,
18013#else
18014 u8 *peer,
18015#endif
18016 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018017{
18018 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18019 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018020 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018021 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018022
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018023 ENTER();
18024
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018025 if (!pAdapter) {
18026 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
18027 return -EINVAL;
18028 }
18029
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018030 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18031 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
18032 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018033 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018034 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070018036 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018037 return -EINVAL;
18038 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018039
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018040 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018041 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018042 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018043 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018044 }
18045
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018046
18047 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018048 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018049 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018051 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
18052 "Cannot process TDLS commands",
18053 pHddCtx->cfg_ini->fEnableTDLSSupport,
18054 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018055 return -ENOTSUPP;
18056 }
18057
18058 switch (oper) {
18059 case NL80211_TDLS_ENABLE_LINK:
18060 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018061 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018062 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053018063 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
18064 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053018065 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018066 tANI_U16 numCurrTdlsPeers = 0;
18067 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018068 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018069 tSirMacAddr peerMac;
18070 int channel;
18071 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018072
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18074 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
18075 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018076
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018077 mutex_lock(&pHddCtx->tdls_lock);
18078 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018079 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053018080 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018081 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018082 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18083 " (oper %d) not exsting. ignored",
18084 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18085 return -EINVAL;
18086 }
18087
18088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18089 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18090 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18091 "NL80211_TDLS_ENABLE_LINK");
18092
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018093 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
18094 {
18095 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
18096 MAC_ADDRESS_STR " failed",
18097 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018098 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018099 return -EINVAL;
18100 }
18101
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018102 /* before starting tdls connection, set tdls
18103 * off channel established status to default value */
18104 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018105
18106 mutex_unlock(&pHddCtx->tdls_lock);
18107
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053018108 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018109 /* TDLS Off Channel, Disable tdls channel switch,
18110 when there are more than one tdls link */
18111 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053018112 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018113 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018114 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018115 /* get connected peer and send disable tdls off chan */
18116 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018117 if ((connPeer) &&
18118 (connPeer->isOffChannelSupported == TRUE) &&
18119 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018120 {
18121 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18122 "%s: More then one peer connected, Disable "
18123 "TDLS channel switch", __func__);
18124
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018125 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018126 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
18127 channel = connPeer->peerParams.channel;
18128
18129 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018130
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018131 ret = sme_SendTdlsChanSwitchReq(
18132 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018133 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018134 peerMac,
18135 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018136 TDLS_OFF_CHANNEL_BW_OFFSET,
18137 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018138 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018139 hddLog(VOS_TRACE_LEVEL_ERROR,
18140 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018141 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018142 }
18143 else
18144 {
18145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18146 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018147 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018148 "isOffChannelConfigured %d",
18149 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018150 (connPeer ? (connPeer->isOffChannelSupported)
18151 : -1),
18152 (connPeer ? (connPeer->isOffChannelConfigured)
18153 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018154 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018155 }
18156 }
18157
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018158 mutex_lock(&pHddCtx->tdls_lock);
18159 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18160 if ( NULL == pTdlsPeer ) {
18161 mutex_unlock(&pHddCtx->tdls_lock);
18162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18163 "%s: " MAC_ADDRESS_STR
18164 " (oper %d) peer got freed in other context. ignored",
18165 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18166 return -EINVAL;
18167 }
18168 peer_status = pTdlsPeer->link_status;
18169 mutex_unlock(&pHddCtx->tdls_lock);
18170
18171 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018172 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018173 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053018174
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018175 if (0 != wlan_hdd_tdls_get_link_establish_params(
18176 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018177 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018178 return -EINVAL;
18179 }
18180 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018181
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018182 ret = sme_SendTdlsLinkEstablishParams(
18183 WLAN_HDD_GET_HAL_CTX(pAdapter),
18184 pAdapter->sessionId, peer,
18185 &tdlsLinkEstablishParams);
18186 if (ret != VOS_STATUS_SUCCESS) {
18187 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
18188 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018189 /* Send TDLS peer UAPSD capabilities to the firmware and
18190 * register with the TL on after the response for this operation
18191 * is received .
18192 */
18193 ret = wait_for_completion_interruptible_timeout(
18194 &pAdapter->tdls_link_establish_req_comp,
18195 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053018196
18197 mutex_lock(&pHddCtx->tdls_lock);
18198 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18199 if ( NULL == pTdlsPeer ) {
18200 mutex_unlock(&pHddCtx->tdls_lock);
18201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18202 "%s %d: " MAC_ADDRESS_STR
18203 " (oper %d) peer got freed in other context. ignored",
18204 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
18205 (int)oper);
18206 return -EINVAL;
18207 }
18208 peer_status = pTdlsPeer->link_status;
18209 mutex_unlock(&pHddCtx->tdls_lock);
18210
18211 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018212 {
18213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018214 FL("Link Establish Request Failed Status %ld"),
18215 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018216 return -EINVAL;
18217 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018218 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018219
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018220 mutex_lock(&pHddCtx->tdls_lock);
18221 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18222 if ( NULL == pTdlsPeer ) {
18223 mutex_unlock(&pHddCtx->tdls_lock);
18224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18225 "%s: " MAC_ADDRESS_STR
18226 " (oper %d) peer got freed in other context. ignored",
18227 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18228 return -EINVAL;
18229 }
18230
Atul Mittal115287b2014-07-08 13:26:33 +053018231 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18232 eTDLS_LINK_CONNECTED,
18233 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018234 staDesc.ucSTAId = pTdlsPeer->staId;
18235 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053018236
18237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18238 "%s: tdlsLinkEstablishParams of peer "
18239 MAC_ADDRESS_STR "uapsdQueues: %d"
18240 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
18241 "isResponder: %d peerstaId: %d",
18242 __func__,
18243 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
18244 tdlsLinkEstablishParams.uapsdQueues,
18245 tdlsLinkEstablishParams.qos,
18246 tdlsLinkEstablishParams.maxSp,
18247 tdlsLinkEstablishParams.isBufSta,
18248 tdlsLinkEstablishParams.isOffChannelSupported,
18249 tdlsLinkEstablishParams.isResponder,
18250 pTdlsPeer->staId);
18251
18252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18253 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
18254 __func__,
18255 staDesc.ucSTAId,
18256 staDesc.ucQosEnabled);
18257
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018258 ret = WLANTL_UpdateTdlsSTAClient(
18259 pHddCtx->pvosContext,
18260 &staDesc);
18261 if (ret != VOS_STATUS_SUCCESS) {
18262 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
18263 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053018264
Gopichand Nakkala471708b2013-06-04 20:03:01 +053018265 /* Mark TDLS client Authenticated .*/
18266 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
18267 pTdlsPeer->staId,
18268 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018269 if (VOS_STATUS_SUCCESS == status)
18270 {
Hoonki Lee14621352013-04-16 17:51:19 -070018271 if (pTdlsPeer->is_responder == 0)
18272 {
18273 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018274 tdlsConnInfo_t *tdlsInfo;
18275
18276 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
18277
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018278 if (!vos_timer_is_initialized(
18279 &pTdlsPeer->initiatorWaitTimeoutTimer))
18280 {
18281 /* Initialize initiator wait callback */
18282 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018283 &pTdlsPeer->initiatorWaitTimeoutTimer,
18284 VOS_TIMER_TYPE_SW,
18285 wlan_hdd_tdls_initiator_wait_cb,
18286 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018287 }
Hoonki Lee14621352013-04-16 17:51:19 -070018288 wlan_hdd_tdls_timer_restart(pAdapter,
18289 &pTdlsPeer->initiatorWaitTimeoutTimer,
18290 WAIT_TIME_TDLS_INITIATOR);
18291 /* suspend initiator TX until it receives direct packet from the
18292 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018293 ret = WLANTL_SuspendDataTx(
18294 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18295 &staId, NULL);
18296 if (ret != VOS_STATUS_SUCCESS) {
18297 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
18298 }
Hoonki Lee14621352013-04-16 17:51:19 -070018299 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018300
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018301 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018302 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018303 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018304 suppChannelLen =
18305 tdlsLinkEstablishParams.supportedChannelsLen;
18306
18307 if ((suppChannelLen > 0) &&
18308 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
18309 {
18310 tANI_U8 suppPeerChannel = 0;
18311 int i = 0;
18312 for (i = 0U; i < suppChannelLen; i++)
18313 {
18314 suppPeerChannel =
18315 tdlsLinkEstablishParams.supportedChannels[i];
18316
18317 pTdlsPeer->isOffChannelSupported = FALSE;
18318 if (suppPeerChannel ==
18319 pTdlsPeer->peerParams.channel)
18320 {
18321 pTdlsPeer->isOffChannelSupported = TRUE;
18322 break;
18323 }
18324 }
18325 }
18326 else
18327 {
18328 pTdlsPeer->isOffChannelSupported = FALSE;
18329 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018330 }
18331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18332 "%s: TDLS channel switch request for channel "
18333 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018334 "%d isOffChannelSupported %d", __func__,
18335 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018336 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018337 suppChannelLen,
18338 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018339
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018340 /* TDLS Off Channel, Enable tdls channel switch,
18341 when their is only one tdls link and it supports */
18342 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18343 if ((numCurrTdlsPeers == 1) &&
18344 (TRUE == pTdlsPeer->isOffChannelSupported) &&
18345 (TRUE == pTdlsPeer->isOffChannelConfigured))
18346 {
18347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18348 "%s: Send TDLS channel switch request for channel %d",
18349 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018350
18351 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018352 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
18353 channel = pTdlsPeer->peerParams.channel;
18354
18355 mutex_unlock(&pHddCtx->tdls_lock);
18356
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018357 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
18358 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018359 peerMac,
18360 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018361 TDLS_OFF_CHANNEL_BW_OFFSET,
18362 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018363 if (ret != VOS_STATUS_SUCCESS) {
18364 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
18365 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018366 }
18367 else
18368 {
18369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18370 "%s: TDLS channel switch request not sent"
18371 " numCurrTdlsPeers %d "
18372 "isOffChannelSupported %d "
18373 "isOffChannelConfigured %d",
18374 __func__, numCurrTdlsPeers,
18375 pTdlsPeer->isOffChannelSupported,
18376 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018377 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018378 }
18379
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018380 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018381 else
18382 mutex_unlock(&pHddCtx->tdls_lock);
18383
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018384 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018385
18386 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018387 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18388 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018389 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018390 int ac;
18391 uint8 ucAc[4] = { WLANTL_AC_VO,
18392 WLANTL_AC_VI,
18393 WLANTL_AC_BK,
18394 WLANTL_AC_BE };
18395 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18396 for(ac=0; ac < 4; ac++)
18397 {
18398 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18399 pTdlsPeer->staId, ucAc[ac],
18400 tlTid[ac], tlTid[ac], 0, 0,
18401 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018402 if (status != VOS_STATUS_SUCCESS) {
18403 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18404 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018405 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018406 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018407 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018408
Bhargav Shah66896792015-10-01 18:17:37 +053018409 /* stop TCP delack timer if TDLS is enable */
18410 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18411 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053018412 hdd_wlan_tdls_enable_link_event(peer,
18413 pTdlsPeer->isOffChannelSupported,
18414 pTdlsPeer->isOffChannelConfigured,
18415 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018416 }
18417 break;
18418 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018419 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018420 tANI_U16 numCurrTdlsPeers = 0;
18421 hddTdlsPeer_t *connPeer = NULL;
18422
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18424 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18425 __func__, MAC_ADDR_ARRAY(peer));
18426
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018427 mutex_lock(&pHddCtx->tdls_lock);
18428 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018429
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018430
Sunil Dutt41de4e22013-11-14 18:09:02 +053018431 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018432 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018433 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18434 " (oper %d) not exsting. ignored",
18435 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18436 return -EINVAL;
18437 }
18438
18439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18440 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18441 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18442 "NL80211_TDLS_DISABLE_LINK");
18443
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018444 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018445 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018446 long status;
18447
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018448 /* set tdls off channel status to false for this peer */
18449 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018450 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18451 eTDLS_LINK_TEARING,
18452 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18453 eTDLS_LINK_UNSPECIFIED:
18454 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018455 mutex_unlock(&pHddCtx->tdls_lock);
18456
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018457 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18458
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018459 status = sme_DeleteTdlsPeerSta(
18460 WLAN_HDD_GET_HAL_CTX(pAdapter),
18461 pAdapter->sessionId, peer );
18462 if (status != VOS_STATUS_SUCCESS) {
18463 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18464 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018465
18466 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18467 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018468
18469 mutex_lock(&pHddCtx->tdls_lock);
18470 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18471 if ( NULL == pTdlsPeer ) {
18472 mutex_unlock(&pHddCtx->tdls_lock);
18473 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18474 " peer was freed in other context",
18475 __func__, MAC_ADDR_ARRAY(peer));
18476 return -EINVAL;
18477 }
18478
Atul Mittal271a7652014-09-12 13:18:22 +053018479 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053018480 eTDLS_LINK_IDLE,
18481 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018482 mutex_unlock(&pHddCtx->tdls_lock);
18483
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018484 if (status <= 0)
18485 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18487 "%s: Del station failed status %ld",
18488 __func__, status);
18489 return -EPERM;
18490 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018491
18492 /* TDLS Off Channel, Enable tdls channel switch,
18493 when their is only one tdls link and it supports */
18494 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18495 if (numCurrTdlsPeers == 1)
18496 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018497 tSirMacAddr peerMac;
18498 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018499
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018500 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018501 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018502
18503 if (connPeer == NULL) {
18504 mutex_unlock(&pHddCtx->tdls_lock);
18505 hddLog(VOS_TRACE_LEVEL_ERROR,
18506 "%s connPeer is NULL", __func__);
18507 return -EINVAL;
18508 }
18509
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018510 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18511 channel = connPeer->peerParams.channel;
18512
18513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18514 "%s: TDLS channel switch "
18515 "isOffChannelSupported %d "
18516 "isOffChannelConfigured %d "
18517 "isOffChannelEstablished %d",
18518 __func__,
18519 (connPeer ? connPeer->isOffChannelSupported : -1),
18520 (connPeer ? connPeer->isOffChannelConfigured : -1),
18521 (connPeer ? connPeer->isOffChannelEstablished : -1));
18522
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018523 if ((connPeer) &&
18524 (connPeer->isOffChannelSupported == TRUE) &&
18525 (connPeer->isOffChannelConfigured == TRUE))
18526 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018527 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018528 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018529 status = sme_SendTdlsChanSwitchReq(
18530 WLAN_HDD_GET_HAL_CTX(pAdapter),
18531 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018532 peerMac,
18533 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018534 TDLS_OFF_CHANNEL_BW_OFFSET,
18535 TDLS_CHANNEL_SWITCH_ENABLE);
18536 if (status != VOS_STATUS_SUCCESS) {
18537 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18538 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018539 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018540 else
18541 mutex_unlock(&pHddCtx->tdls_lock);
18542 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018543 else
18544 {
18545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18546 "%s: TDLS channel switch request not sent "
18547 "numCurrTdlsPeers %d ",
18548 __func__, numCurrTdlsPeers);
18549 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018550 }
18551 else
18552 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018553 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18555 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080018556 }
Bhargav Shah66896792015-10-01 18:17:37 +053018557 if (numCurrTdlsPeers == 0) {
18558 /* start TCP delack timer if TDLS is disable */
18559 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18560 hdd_manage_delack_timer(pHddCtx);
18561 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018562 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018563 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018564 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018565 {
Atul Mittal115287b2014-07-08 13:26:33 +053018566 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018567
Atul Mittal115287b2014-07-08 13:26:33 +053018568 if (0 != status)
18569 {
18570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018571 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053018572 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018573 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053018574 break;
18575 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018576 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018577 {
Atul Mittal115287b2014-07-08 13:26:33 +053018578 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
18579 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018580 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053018581 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018582
Atul Mittal115287b2014-07-08 13:26:33 +053018583 if (0 != status)
18584 {
18585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018586 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053018587 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053018588 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053018589 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018590 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018591 case NL80211_TDLS_DISCOVERY_REQ:
18592 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018594 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018595 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018596 return -ENOTSUPP;
18597 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18599 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018600 return -ENOTSUPP;
18601 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018602
18603 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018604 return 0;
18605}
Chilam NG571c65a2013-01-19 12:27:36 +053018606
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018607static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018608#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18609 const u8 *peer,
18610#else
18611 u8 *peer,
18612#endif
18613 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018614{
18615 int ret;
18616
18617 vos_ssr_protect(__func__);
18618 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
18619 vos_ssr_unprotect(__func__);
18620
18621 return ret;
18622}
18623
Chilam NG571c65a2013-01-19 12:27:36 +053018624int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
18625 struct net_device *dev, u8 *peer)
18626{
Arif Hussaina7c8e412013-11-20 11:06:42 -080018627 hddLog(VOS_TRACE_LEVEL_INFO,
18628 "tdls send discover req: "MAC_ADDRESS_STR,
18629 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018630#if TDLS_MGMT_VERSION2
18631 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18632 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18633#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018634#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18635 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18636 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
18637#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18638 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18639 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18640#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18641 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18642 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18643#else
Chilam NG571c65a2013-01-19 12:27:36 +053018644 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18645 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018646#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018647#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053018648}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018649#endif
18650
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018651#ifdef WLAN_FEATURE_GTK_OFFLOAD
18652/*
18653 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
18654 * Callback rountine called upon receiving response for
18655 * get offload info
18656 */
18657void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
18658 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
18659{
18660
18661 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018662 tANI_U8 tempReplayCounter[8];
18663 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018664
18665 ENTER();
18666
18667 if (NULL == pAdapter)
18668 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018670 "%s: HDD adapter is Null", __func__);
18671 return ;
18672 }
18673
18674 if (NULL == pGtkOffloadGetInfoRsp)
18675 {
18676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18677 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
18678 return ;
18679 }
18680
18681 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
18682 {
18683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18684 "%s: wlan Failed to get replay counter value",
18685 __func__);
18686 return ;
18687 }
18688
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018689 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18690 /* Update replay counter */
18691 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
18692 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18693
18694 {
18695 /* changing from little to big endian since supplicant
18696 * works on big endian format
18697 */
18698 int i;
18699 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18700
18701 for (i = 0; i < 8; i++)
18702 {
18703 tempReplayCounter[7-i] = (tANI_U8)p[i];
18704 }
18705 }
18706
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018707 /* Update replay counter to NL */
18708 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018709 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018710}
18711
18712/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018713 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018714 * This function is used to offload GTK rekeying job to the firmware.
18715 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018716int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018717 struct cfg80211_gtk_rekey_data *data)
18718{
18719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18720 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18721 hdd_station_ctx_t *pHddStaCtx;
18722 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018723 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018724 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018725 eHalStatus status = eHAL_STATUS_FAILURE;
18726
18727 ENTER();
18728
18729 if (NULL == pAdapter)
18730 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018732 "%s: HDD adapter is Null", __func__);
18733 return -ENODEV;
18734 }
18735
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018736 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18737 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
18738 pAdapter->sessionId, pAdapter->device_mode));
18739
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018740 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018741 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018742 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018743 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018744 }
18745
18746 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18747 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18748 if (NULL == hHal)
18749 {
18750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18751 "%s: HAL context is Null!!!", __func__);
18752 return -EAGAIN;
18753 }
18754
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018755 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
18756 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
18757 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
18758 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018759 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018760 {
18761 /* changing from big to little endian since driver
18762 * works on little endian format
18763 */
18764 tANI_U8 *p =
18765 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
18766 int i;
18767
18768 for (i = 0; i < 8; i++)
18769 {
18770 p[7-i] = data->replay_ctr[i];
18771 }
18772 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018773
18774 if (TRUE == pHddCtx->hdd_wlan_suspended)
18775 {
18776 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018777 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
18778 sizeof (tSirGtkOffloadParams));
18779 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018780 pAdapter->sessionId);
18781
18782 if (eHAL_STATUS_SUCCESS != status)
18783 {
18784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18785 "%s: sme_SetGTKOffload failed, returned %d",
18786 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018787
18788 /* Need to clear any trace of key value in the memory.
18789 * Thus zero out the memory even though it is local
18790 * variable.
18791 */
18792 vos_mem_zero(&hddGtkOffloadReqParams,
18793 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018794 return status;
18795 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18797 "%s: sme_SetGTKOffload successfull", __func__);
18798 }
18799 else
18800 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18802 "%s: wlan not suspended GTKOffload request is stored",
18803 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018804 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018805
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018806 /* Need to clear any trace of key value in the memory.
18807 * Thus zero out the memory even though it is local
18808 * variable.
18809 */
18810 vos_mem_zero(&hddGtkOffloadReqParams,
18811 sizeof(hddGtkOffloadReqParams));
18812
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018813 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018814 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018815}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018816
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018817int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
18818 struct cfg80211_gtk_rekey_data *data)
18819{
18820 int ret;
18821
18822 vos_ssr_protect(__func__);
18823 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
18824 vos_ssr_unprotect(__func__);
18825
18826 return ret;
18827}
18828#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018829/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018830 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018831 * This function is used to set access control policy
18832 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018833static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18834 struct net_device *dev,
18835 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018836{
18837 int i;
18838 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18839 hdd_hostapd_state_t *pHostapdState;
18840 tsap_Config_t *pConfig;
18841 v_CONTEXT_t pVosContext = NULL;
18842 hdd_context_t *pHddCtx;
18843 int status;
18844
18845 ENTER();
18846
18847 if (NULL == pAdapter)
18848 {
18849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18850 "%s: HDD adapter is Null", __func__);
18851 return -ENODEV;
18852 }
18853
18854 if (NULL == params)
18855 {
18856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18857 "%s: params is Null", __func__);
18858 return -EINVAL;
18859 }
18860
18861 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18862 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018863 if (0 != status)
18864 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018865 return status;
18866 }
18867
18868 pVosContext = pHddCtx->pvosContext;
18869 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
18870
18871 if (NULL == pHostapdState)
18872 {
18873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18874 "%s: pHostapdState is Null", __func__);
18875 return -EINVAL;
18876 }
18877
18878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
18879 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018880 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18881 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
18882 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018883
18884 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
18885 {
18886 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
18887
18888 /* default value */
18889 pConfig->num_accept_mac = 0;
18890 pConfig->num_deny_mac = 0;
18891
18892 /**
18893 * access control policy
18894 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
18895 * listed in hostapd.deny file.
18896 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
18897 * listed in hostapd.accept file.
18898 */
18899 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
18900 {
18901 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
18902 }
18903 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
18904 {
18905 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
18906 }
18907 else
18908 {
18909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18910 "%s:Acl Policy : %d is not supported",
18911 __func__, params->acl_policy);
18912 return -ENOTSUPP;
18913 }
18914
18915 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
18916 {
18917 pConfig->num_accept_mac = params->n_acl_entries;
18918 for (i = 0; i < params->n_acl_entries; i++)
18919 {
18920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18921 "** Add ACL MAC entry %i in WhiletList :"
18922 MAC_ADDRESS_STR, i,
18923 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18924
18925 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
18926 sizeof(qcmacaddr));
18927 }
18928 }
18929 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
18930 {
18931 pConfig->num_deny_mac = params->n_acl_entries;
18932 for (i = 0; i < params->n_acl_entries; i++)
18933 {
18934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18935 "** Add ACL MAC entry %i in BlackList :"
18936 MAC_ADDRESS_STR, i,
18937 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18938
18939 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
18940 sizeof(qcmacaddr));
18941 }
18942 }
18943
18944 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
18945 {
18946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18947 "%s: SAP Set Mac Acl fail", __func__);
18948 return -EINVAL;
18949 }
18950 }
18951 else
18952 {
18953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053018954 "%s: Invalid device_mode = %s (%d)",
18955 __func__, hdd_device_modetoString(pAdapter->device_mode),
18956 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018957 return -EINVAL;
18958 }
18959
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018960 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018961 return 0;
18962}
18963
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018964static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18965 struct net_device *dev,
18966 const struct cfg80211_acl_data *params)
18967{
18968 int ret;
18969 vos_ssr_protect(__func__);
18970 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
18971 vos_ssr_unprotect(__func__);
18972
18973 return ret;
18974}
18975
Leo Chang9056f462013-08-01 19:21:11 -070018976#ifdef WLAN_NL80211_TESTMODE
18977#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070018978void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070018979(
18980 void *pAdapter,
18981 void *indCont
18982)
18983{
Leo Changd9df8aa2013-09-26 13:32:26 -070018984 tSirLPHBInd *lphbInd;
18985 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053018986 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070018987
18988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018989 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070018990
c_hpothu73f35e62014-04-18 13:40:08 +053018991 if (pAdapter == NULL)
18992 {
18993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18994 "%s: pAdapter is NULL\n",__func__);
18995 return;
18996 }
18997
Leo Chang9056f462013-08-01 19:21:11 -070018998 if (NULL == indCont)
18999 {
19000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019001 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070019002 return;
19003 }
19004
c_hpothu73f35e62014-04-18 13:40:08 +053019005 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070019006 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070019007 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053019008 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070019009 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070019010 GFP_ATOMIC);
19011 if (!skb)
19012 {
19013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19014 "LPHB timeout, NL buffer alloc fail");
19015 return;
19016 }
19017
Leo Changac3ba772013-10-07 09:47:04 -070019018 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070019019 {
19020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19021 "WLAN_HDD_TM_ATTR_CMD put fail");
19022 goto nla_put_failure;
19023 }
Leo Changac3ba772013-10-07 09:47:04 -070019024 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070019025 {
19026 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19027 "WLAN_HDD_TM_ATTR_TYPE put fail");
19028 goto nla_put_failure;
19029 }
Leo Changac3ba772013-10-07 09:47:04 -070019030 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070019031 sizeof(tSirLPHBInd), lphbInd))
19032 {
19033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19034 "WLAN_HDD_TM_ATTR_DATA put fail");
19035 goto nla_put_failure;
19036 }
Leo Chang9056f462013-08-01 19:21:11 -070019037 cfg80211_testmode_event(skb, GFP_ATOMIC);
19038 return;
19039
19040nla_put_failure:
19041 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19042 "NLA Put fail");
19043 kfree_skb(skb);
19044
19045 return;
19046}
19047#endif /* FEATURE_WLAN_LPHB */
19048
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019049static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070019050{
19051 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
19052 int err = 0;
19053#ifdef FEATURE_WLAN_LPHB
19054 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070019055 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019056
19057 ENTER();
19058
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019059 err = wlan_hdd_validate_context(pHddCtx);
19060 if (0 != err)
19061 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019062 return err;
19063 }
Leo Chang9056f462013-08-01 19:21:11 -070019064#endif /* FEATURE_WLAN_LPHB */
19065
19066 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
19067 if (err)
19068 {
19069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19070 "%s Testmode INV ATTR", __func__);
19071 return err;
19072 }
19073
19074 if (!tb[WLAN_HDD_TM_ATTR_CMD])
19075 {
19076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19077 "%s Testmode INV CMD", __func__);
19078 return -EINVAL;
19079 }
19080
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019081 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19082 TRACE_CODE_HDD_CFG80211_TESTMODE,
19083 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070019084 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
19085 {
19086#ifdef FEATURE_WLAN_LPHB
19087 /* Low Power Heartbeat configuration request */
19088 case WLAN_HDD_TM_CMD_WLAN_HB:
19089 {
19090 int buf_len;
19091 void *buf;
19092 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080019093 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070019094
19095 if (!tb[WLAN_HDD_TM_ATTR_DATA])
19096 {
19097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19098 "%s Testmode INV DATA", __func__);
19099 return -EINVAL;
19100 }
19101
19102 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
19103 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080019104
19105 hb_params_temp =(tSirLPHBReq *)buf;
19106 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
19107 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
19108 return -EINVAL;
19109
Leo Chang9056f462013-08-01 19:21:11 -070019110 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
19111 if (NULL == hb_params)
19112 {
19113 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19114 "%s Request Buffer Alloc Fail", __func__);
19115 return -EINVAL;
19116 }
19117
19118 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070019119 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
19120 hb_params,
19121 wlan_hdd_cfg80211_lphb_ind_handler);
19122 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070019123 {
Leo Changd9df8aa2013-09-26 13:32:26 -070019124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19125 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070019126 vos_mem_free(hb_params);
19127 }
Leo Chang9056f462013-08-01 19:21:11 -070019128 return 0;
19129 }
19130#endif /* FEATURE_WLAN_LPHB */
19131 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19133 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070019134 return -EOPNOTSUPP;
19135 }
19136
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019137 EXIT();
19138 return err;
Leo Chang9056f462013-08-01 19:21:11 -070019139}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019140
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053019141static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
19142#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
19143 struct wireless_dev *wdev,
19144#endif
19145 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019146{
19147 int ret;
19148
19149 vos_ssr_protect(__func__);
19150 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
19151 vos_ssr_unprotect(__func__);
19152
19153 return ret;
19154}
Leo Chang9056f462013-08-01 19:21:11 -070019155#endif /* CONFIG_NL80211_TESTMODE */
19156
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019157static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019158 struct net_device *dev,
19159 int idx, struct survey_info *survey)
19160{
19161 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19162 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053019163 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019164 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053019165 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019166 v_S7_t snr,rssi;
19167 int status, i, j, filled = 0;
19168
19169 ENTER();
19170
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019171 if (NULL == pAdapter)
19172 {
19173 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19174 "%s: HDD adapter is Null", __func__);
19175 return -ENODEV;
19176 }
19177
19178 if (NULL == wiphy)
19179 {
19180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19181 "%s: wiphy is Null", __func__);
19182 return -ENODEV;
19183 }
19184
19185 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19186 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019187 if (0 != status)
19188 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019189 return status;
19190 }
19191
Mihir Sheted9072e02013-08-21 17:02:29 +053019192 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19193
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019194 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053019195 0 != pAdapter->survey_idx ||
19196 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019197 {
19198 /* The survey dump ops when implemented completely is expected to
19199 * return a survey of all channels and the ops is called by the
19200 * kernel with incremental values of the argument 'idx' till it
19201 * returns -ENONET. But we can only support the survey for the
19202 * operating channel for now. survey_idx is used to track
19203 * that the ops is called only once and then return -ENONET for
19204 * the next iteration
19205 */
19206 pAdapter->survey_idx = 0;
19207 return -ENONET;
19208 }
19209
Mukul Sharma9d5233b2015-06-11 20:28:20 +053019210 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
19211 {
19212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19213 "%s: Roaming in progress, hence return ", __func__);
19214 return -ENONET;
19215 }
19216
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019217 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19218
19219 wlan_hdd_get_snr(pAdapter, &snr);
19220 wlan_hdd_get_rssi(pAdapter, &rssi);
19221
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019222 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19223 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
19224 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019225 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
19226 hdd_wlan_get_freq(channel, &freq);
19227
19228
19229 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
19230 {
19231 if (NULL == wiphy->bands[i])
19232 {
19233 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
19234 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
19235 continue;
19236 }
19237
19238 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
19239 {
19240 struct ieee80211_supported_band *band = wiphy->bands[i];
19241
19242 if (band->channels[j].center_freq == (v_U16_t)freq)
19243 {
19244 survey->channel = &band->channels[j];
19245 /* The Rx BDs contain SNR values in dB for the received frames
19246 * while the supplicant expects noise. So we calculate and
19247 * return the value of noise (dBm)
19248 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
19249 */
19250 survey->noise = rssi - snr;
19251 survey->filled = SURVEY_INFO_NOISE_DBM;
19252 filled = 1;
19253 }
19254 }
19255 }
19256
19257 if (filled)
19258 pAdapter->survey_idx = 1;
19259 else
19260 {
19261 pAdapter->survey_idx = 0;
19262 return -ENONET;
19263 }
19264
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019265 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019266 return 0;
19267}
19268
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019269static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
19270 struct net_device *dev,
19271 int idx, struct survey_info *survey)
19272{
19273 int ret;
19274
19275 vos_ssr_protect(__func__);
19276 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
19277 vos_ssr_unprotect(__func__);
19278
19279 return ret;
19280}
19281
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019282/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019283 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019284 * this is called when cfg80211 driver resume
19285 * driver updates latest sched_scan scan result(if any) to cfg80211 database
19286 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019287int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019288{
19289 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19290 hdd_adapter_t *pAdapter;
19291 hdd_adapter_list_node_t *pAdapterNode, *pNext;
19292 VOS_STATUS status = VOS_STATUS_SUCCESS;
19293
19294 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019295
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019296 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019297 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019298 return 0;
19299 }
19300
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019301 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
19302 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019303 spin_lock(&pHddCtx->schedScan_lock);
19304 pHddCtx->isWiphySuspended = FALSE;
19305 if (TRUE != pHddCtx->isSchedScanUpdatePending)
19306 {
19307 spin_unlock(&pHddCtx->schedScan_lock);
19308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19309 "%s: Return resume is not due to PNO indication", __func__);
19310 return 0;
19311 }
19312 // Reset flag to avoid updatating cfg80211 data old results again
19313 pHddCtx->isSchedScanUpdatePending = FALSE;
19314 spin_unlock(&pHddCtx->schedScan_lock);
19315
19316 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
19317
19318 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
19319 {
19320 pAdapter = pAdapterNode->pAdapter;
19321 if ( (NULL != pAdapter) &&
19322 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
19323 {
19324 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019325 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19327 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019328 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019329 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019330 {
19331 /* Acquire wakelock to handle the case where APP's tries to
19332 * suspend immediately after updating the scan results. Whis
19333 * results in app's is in suspended state and not able to
19334 * process the connect request to AP
19335 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053019336 hdd_prevent_suspend_timeout(2000,
19337 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019338 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019339 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019340
19341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19342 "%s : cfg80211 scan result database updated", __func__);
19343
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019344 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019345 return 0;
19346
19347 }
19348 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19349 pAdapterNode = pNext;
19350 }
19351
19352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19353 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019354 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019355 return 0;
19356}
19357
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019358int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
19359{
19360 int ret;
19361
19362 vos_ssr_protect(__func__);
19363 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
19364 vos_ssr_unprotect(__func__);
19365
19366 return ret;
19367}
19368
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019369/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019370 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019371 * this is called when cfg80211 driver suspends
19372 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019373int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019374 struct cfg80211_wowlan *wow)
19375{
19376 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019377 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019378
19379 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019380
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019381 ret = wlan_hdd_validate_context(pHddCtx);
19382 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019383 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019384 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019385 }
19386
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019387
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019388 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19389 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
19390 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019391 pHddCtx->isWiphySuspended = TRUE;
19392
19393 EXIT();
19394
19395 return 0;
19396}
19397
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019398int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19399 struct cfg80211_wowlan *wow)
19400{
19401 int ret;
19402
19403 vos_ssr_protect(__func__);
19404 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19405 vos_ssr_unprotect(__func__);
19406
19407 return ret;
19408}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019409
19410#ifdef FEATURE_OEM_DATA_SUPPORT
19411static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019412 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019413{
19414 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19415
19416 ENTER();
19417
19418 if (wlan_hdd_validate_context(pHddCtx)) {
19419 return;
19420 }
19421 if (!pMsg)
19422 {
19423 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
19424 return;
19425 }
19426
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019427 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019428
19429 EXIT();
19430 return;
19431
19432}
19433
19434void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019435 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019436{
19437 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19438
19439 ENTER();
19440
19441 if (wlan_hdd_validate_context(pHddCtx)) {
19442 return;
19443 }
19444
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019445 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019446
19447 switch(evType) {
19448 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019449 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019450 break;
19451 default:
19452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
19453 break;
19454 }
19455 EXIT();
19456}
19457#endif
19458
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019459#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19460 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019461/**
19462 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
19463 * @wiphy: Pointer to wiphy
19464 * @wdev: Pointer to wireless device structure
19465 *
19466 * This function is used to abort an ongoing scan
19467 *
19468 * Return: None
19469 */
19470static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19471 struct wireless_dev *wdev)
19472{
19473 struct net_device *dev = wdev->netdev;
19474 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
19475 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
19476 int ret;
19477
19478 ENTER();
19479
19480 if (NULL == adapter) {
19481 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
19482 return;
19483 }
19484
19485 ret = wlan_hdd_validate_context(hdd_ctx);
19486 if (0 != ret)
19487 return;
19488
19489 wlan_hdd_scan_abort(adapter);
19490
19491 return;
19492}
19493
19494/**
19495 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
19496 * @wiphy: Pointer to wiphy
19497 * @wdev: Pointer to wireless device structure
19498 *
19499 * Return: None
19500 */
19501void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19502 struct wireless_dev *wdev)
19503{
19504 vos_ssr_protect(__func__);
19505 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
19506 vos_ssr_unprotect(__func__);
19507
19508 return;
19509}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019510#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019511
Jeff Johnson295189b2012-06-20 16:38:30 -070019512/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019513static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070019514{
19515 .add_virtual_intf = wlan_hdd_add_virtual_intf,
19516 .del_virtual_intf = wlan_hdd_del_virtual_intf,
19517 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
19518 .change_station = wlan_hdd_change_station,
19519#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
19520 .add_beacon = wlan_hdd_cfg80211_add_beacon,
19521 .del_beacon = wlan_hdd_cfg80211_del_beacon,
19522 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019523#else
19524 .start_ap = wlan_hdd_cfg80211_start_ap,
19525 .change_beacon = wlan_hdd_cfg80211_change_beacon,
19526 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070019527#endif
19528 .change_bss = wlan_hdd_cfg80211_change_bss,
19529 .add_key = wlan_hdd_cfg80211_add_key,
19530 .get_key = wlan_hdd_cfg80211_get_key,
19531 .del_key = wlan_hdd_cfg80211_del_key,
19532 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019533#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070019534 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019535#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019536 .scan = wlan_hdd_cfg80211_scan,
19537 .connect = wlan_hdd_cfg80211_connect,
19538 .disconnect = wlan_hdd_cfg80211_disconnect,
19539 .join_ibss = wlan_hdd_cfg80211_join_ibss,
19540 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
19541 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
19542 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
19543 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070019544 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
19545 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053019546 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070019547#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19548 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
19549 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
19550 .set_txq_params = wlan_hdd_set_txq_params,
19551#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019552 .get_station = wlan_hdd_cfg80211_get_station,
19553 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
19554 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019555 .add_station = wlan_hdd_cfg80211_add_station,
19556#ifdef FEATURE_WLAN_LFR
19557 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
19558 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
19559 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
19560#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019561#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
19562 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
19563#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019564#ifdef FEATURE_WLAN_TDLS
19565 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
19566 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
19567#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019568#ifdef WLAN_FEATURE_GTK_OFFLOAD
19569 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
19570#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019571#ifdef FEATURE_WLAN_SCAN_PNO
19572 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
19573 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
19574#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019575 .resume = wlan_hdd_cfg80211_resume_wlan,
19576 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019577 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070019578#ifdef WLAN_NL80211_TESTMODE
19579 .testmode_cmd = wlan_hdd_cfg80211_testmode,
19580#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019581 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019582#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19583 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019584 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019585#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019586};
19587