blob: bf92b2cc07142f82581b4b01ab1e007ded02e289 [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
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012627
12628/**
12629 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
12630 * @scan_req: scan request to be checked
12631 *
12632 * Return: true or false
12633 */
12634#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
12635static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
12636 cfg80211_scan_request
12637 *scan_req)
12638{
12639 if (!scan_req || !scan_req->wiphy) {
12640 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
12641 return false;
12642 }
12643 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
12644 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
12645 return false;
12646 }
12647 return true;
12648}
12649#else
12650static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
12651 cfg80211_scan_request
12652 *scan_req)
12653{
12654 if (!scan_req || !scan_req->wiphy) {
12655 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
12656 return false;
12657 }
12658 return true;
12659}
12660#endif
12661
12662
Jeff Johnson295189b2012-06-20 16:38:30 -070012663/*
12664 * FUNCTION: hdd_cfg80211_scan_done_callback
12665 * scanning callback function, called after finishing scan
12666 *
12667 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012668static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012669 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12670{
12671 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012672 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012673 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012674 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012675 struct cfg80211_scan_request *req = NULL;
12676 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012677 bool aborted = false;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012678#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12679 bool iface_down = false;
12680#endif
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012681 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012682 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012683 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012684
12685 ENTER();
12686
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012687 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012688 if (NULL == pHddCtx) {
12689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012690 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012691 }
12692
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012693#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12694 if (!(pAdapter->dev->flags & IFF_UP))
12695 {
12696 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012697 iface_down = true;
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012698 }
12699#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012700 pScanInfo = &pHddCtx->scan_info;
12701
Jeff Johnson295189b2012-06-20 16:38:30 -070012702 hddLog(VOS_TRACE_LEVEL_INFO,
12703 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012704 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012705 __func__, halHandle, pContext, (int) scanId, (int) status);
12706
Kiet Lamac06e2c2013-10-23 16:25:07 +053012707 pScanInfo->mScanPendingCounter = 0;
12708
Jeff Johnson295189b2012-06-20 16:38:30 -070012709 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012710 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012711 &pScanInfo->scan_req_completion_event,
12712 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012713 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012714 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012715 hddLog(VOS_TRACE_LEVEL_ERROR,
12716 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012717 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012718 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012719 }
12720
Yue Maef608272013-04-08 23:09:17 -070012721 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012722 {
12723 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012724 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012725 }
12726
12727 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012728 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012729 {
12730 hddLog(VOS_TRACE_LEVEL_INFO,
12731 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012732 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012733 (int) scanId);
12734 }
12735
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012736#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012737 if (!iface_down)
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012738#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012739 {
12740 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
12741 pAdapter);
12742 if (0 > ret)
12743 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012744 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012745
Jeff Johnson295189b2012-06-20 16:38:30 -070012746 /* If any client wait scan result through WEXT
12747 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012748 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012749 {
12750 /* The other scan request waiting for current scan finish
12751 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012752 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012753 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012754 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012755 }
12756 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012757 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012758 {
12759 struct net_device *dev = pAdapter->dev;
12760 union iwreq_data wrqu;
12761 int we_event;
12762 char *msg;
12763
12764 memset(&wrqu, '\0', sizeof(wrqu));
12765 we_event = SIOCGIWSCAN;
12766 msg = NULL;
12767 wireless_send_event(dev, we_event, &wrqu, msg);
12768 }
12769 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012770 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012771
12772 /* Get the Scan Req */
12773 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053012774 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012775
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012776 /* Scan is no longer pending */
12777 pScanInfo->mScanPending = VOS_FALSE;
12778
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012779 if (!wlan_hdd_cfg80211_validate_scan_req(req))
Jeff Johnson295189b2012-06-20 16:38:30 -070012780 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012781#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
12783 iface_down ? "up" : "down");
12784#endif
12785
12786 if (pAdapter->dev) {
12787 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
12788 pAdapter->dev->name);
12789 }
mukul sharmae7041822015-12-03 15:09:21 +053012790 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070012791 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012792 }
12793
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012794 /* last_scan_timestamp is used to decide if new scan
12795 * is needed or not on station interface. If last station
12796 * scan time and new station scan time is less then
12797 * last_scan_timestamp ; driver will return cached scan.
12798 */
12799 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12800 {
12801 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12802
12803 if ( req->n_channels )
12804 {
12805 for (i = 0; i < req->n_channels ; i++ )
12806 {
12807 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12808 }
12809 /* store no of channel scanned */
12810 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
12811 }
12812
12813 }
12814
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070012815 /*
12816 * cfg80211_scan_done informing NL80211 about completion
12817 * of scanning
12818 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012819 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
12820 {
12821 aborted = true;
12822 }
mukul sharmae7041822015-12-03 15:09:21 +053012823
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012824#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12825 if (!iface_down)
12826#endif
12827 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053012828
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012829 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070012830
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012831allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053012832 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
12833 ) && (pHddCtx->spoofMacAddr.isEnabled
12834 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053012835 /* Generate new random mac addr for next scan */
12836 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053012837
12838 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
12839 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053012840 }
12841
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012842 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012843 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012844
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012845 /* Acquire wakelock to handle the case where APP's tries to suspend
12846 * immediatly after the driver gets connect request(i.e after scan)
12847 * from supplicant, this result in app's is suspending and not able
12848 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012849 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012850
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012851#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12852 if (!iface_down)
12853#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012854#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012855 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012856#endif
12857
Jeff Johnson295189b2012-06-20 16:38:30 -070012858 EXIT();
12859 return 0;
12860}
12861
12862/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053012863 * FUNCTION: hdd_isConnectionInProgress
12864 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012865 *
12866 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012867v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012868{
12869 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12870 hdd_station_ctx_t *pHddStaCtx = NULL;
12871 hdd_adapter_t *pAdapter = NULL;
12872 VOS_STATUS status = 0;
12873 v_U8_t staId = 0;
12874 v_U8_t *staMac = NULL;
12875
c_hpothu9b781ba2013-12-30 20:57:45 +053012876 if (TRUE == pHddCtx->btCoexModeSet)
12877 {
12878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053012879 FL("BTCoex Mode operation in progress"));
12880 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053012881 }
12882
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012883 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12884
12885 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12886 {
12887 pAdapter = pAdapterNode->pAdapter;
12888
12889 if( pAdapter )
12890 {
12891 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012892 "%s: Adapter with device mode %s (%d) exists",
12893 __func__, hdd_device_modetoString(pAdapter->device_mode),
12894 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012895 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053012896 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12897 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
12898 (eConnectionState_Connecting ==
12899 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12900 {
12901 hddLog(VOS_TRACE_LEVEL_ERROR,
12902 "%s: %p(%d) Connection is in progress", __func__,
12903 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12904 return VOS_TRUE;
12905 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012906 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053012907 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012908 {
12909 hddLog(VOS_TRACE_LEVEL_ERROR,
12910 "%s: %p(%d) Reassociation is in progress", __func__,
12911 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12912 return VOS_TRUE;
12913 }
12914 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012915 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12916 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012917 {
12918 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12919 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012920 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012921 {
12922 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
12923 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012924 "%s: client " MAC_ADDRESS_STR
12925 " is in the middle of WPS/EAPOL exchange.", __func__,
12926 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012927 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012928 }
12929 }
12930 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
12931 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
12932 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012933 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12934 ptSapContext pSapCtx = NULL;
12935 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12936 if(pSapCtx == NULL){
12937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12938 FL("psapCtx is NULL"));
12939 return VOS_FALSE;
12940 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012941 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
12942 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012943 if ((pSapCtx->aStaInfo[staId].isUsed) &&
12944 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012945 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012946 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012947
12948 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012949 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
12950 "middle of WPS/EAPOL exchange.", __func__,
12951 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012952 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012953 }
12954 }
12955 }
12956 }
12957 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12958 pAdapterNode = pNext;
12959 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053012960 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012961}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012962
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053012963/**
12964 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
12965 * to the Scan request
12966 * @scanRequest: Pointer to the csr scan request
12967 * @request: Pointer to the scan request from supplicant
12968 *
12969 * Return: None
12970 */
12971#ifdef CFG80211_SCAN_BSSID
12972static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
12973 struct cfg80211_scan_request *request)
12974{
12975 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
12976}
12977#else
12978static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
12979 struct cfg80211_scan_request *request)
12980{
12981}
12982#endif
12983
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012984/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012985 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070012986 * this scan respond to scan trigger and update cfg80211 scan database
12987 * later, scan dump command can be used to recieve scan results
12988 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012989int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080012990#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12991 struct net_device *dev,
12992#endif
12993 struct cfg80211_scan_request *request)
12994{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012995 hdd_adapter_t *pAdapter = NULL;
12996 hdd_context_t *pHddCtx = NULL;
12997 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012998 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012999 tCsrScanRequest scanRequest;
13000 tANI_U8 *channelList = NULL, i;
13001 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013002 int status;
13003 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013004 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013005 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053013006 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013007 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013008
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013009#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
13010 struct net_device *dev = NULL;
13011 if (NULL == request)
13012 {
13013 hddLog(VOS_TRACE_LEVEL_ERROR,
13014 "%s: scan req param null", __func__);
13015 return -EINVAL;
13016 }
13017 dev = request->wdev->netdev;
13018#endif
13019
13020 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13021 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
13022 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13023
Jeff Johnson295189b2012-06-20 16:38:30 -070013024 ENTER();
13025
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013026 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13027 __func__, hdd_device_modetoString(pAdapter->device_mode),
13028 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013029
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013030 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013031 if (0 != status)
13032 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013033 return status;
13034 }
13035
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013036 if (NULL == pwextBuf)
13037 {
13038 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
13039 __func__);
13040 return -EIO;
13041 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013042 cfg_param = pHddCtx->cfg_ini;
13043 pScanInfo = &pHddCtx->scan_info;
13044
Jeff Johnson295189b2012-06-20 16:38:30 -070013045#ifdef WLAN_BTAMP_FEATURE
13046 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013047 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013048 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013049 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013050 "%s: No scanning when AMP is on", __func__);
13051 return -EOPNOTSUPP;
13052 }
13053#endif
13054 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013055 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013056 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013057 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013058 "%s: Not scanning on device_mode = %s (%d)",
13059 __func__, hdd_device_modetoString(pAdapter->device_mode),
13060 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013061 return -EOPNOTSUPP;
13062 }
13063
13064 if (TRUE == pScanInfo->mScanPending)
13065 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013066 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13067 {
13068 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13069 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013070 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013071 }
13072
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013073 // Don't allow scan if PNO scan is going on.
13074 if (pHddCtx->isPnoEnable)
13075 {
13076 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13077 FL("pno scan in progress"));
13078 return -EBUSY;
13079 }
13080
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013081 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013082 //Channel and action frame is pending
13083 //Otherwise Cancel Remain On Channel and allow Scan
13084 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013085 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013086 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013087 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013088 return -EBUSY;
13089 }
13090
Jeff Johnson295189b2012-06-20 16:38:30 -070013091 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13092 {
13093 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013094 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013095 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013096 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013097 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13098 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013099 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013100 "%s: MAX TM Level Scan not allowed", __func__);
13101 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013102 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013103 }
13104 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13105
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013106 /* Check if scan is allowed at this point of time.
13107 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013108 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013109 {
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
13111 if (SCAN_ABORT_THRESHOLD < pHddCtx->con_scan_abort_cnt) {
13112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13113 FL("Triggering SSR, SSR status = %d"), status);
13114 vos_wlanRestart();
13115 }
13116 else
13117 pHddCtx->con_scan_abort_cnt++;
13118
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013119 return -EBUSY;
13120 }
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013121 pHddCtx->con_scan_abort_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013122
Jeff Johnson295189b2012-06-20 16:38:30 -070013123 vos_mem_zero( &scanRequest, sizeof(scanRequest));
13124
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013125 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
13126 * Becasue of this, driver is assuming that this is not wildcard scan and so
13127 * is not aging out the scan results.
13128 */
13129 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070013130 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013131 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013132 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013133
13134 if ((request->ssids) && (0 < request->n_ssids))
13135 {
13136 tCsrSSIDInfo *SsidInfo;
13137 int j;
13138 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
13139 /* Allocate num_ssid tCsrSSIDInfo structure */
13140 SsidInfo = scanRequest.SSIDs.SSIDList =
13141 ( tCsrSSIDInfo *)vos_mem_malloc(
13142 request->n_ssids*sizeof(tCsrSSIDInfo));
13143
13144 if(NULL == scanRequest.SSIDs.SSIDList)
13145 {
13146 hddLog(VOS_TRACE_LEVEL_ERROR,
13147 "%s: memory alloc failed SSIDInfo buffer", __func__);
13148 return -ENOMEM;
13149 }
13150
13151 /* copy all the ssid's and their length */
13152 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
13153 {
13154 /* get the ssid length */
13155 SsidInfo->SSID.length = request->ssids[j].ssid_len;
13156 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
13157 SsidInfo->SSID.length);
13158 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
13159 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
13160 j, SsidInfo->SSID.ssId);
13161 }
13162 /* set the scan type to active */
13163 scanRequest.scanType = eSIR_ACTIVE_SCAN;
13164 }
13165 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013166 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013167 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13168 TRACE_CODE_HDD_CFG80211_SCAN,
13169 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070013170 /* set the scan type to active */
13171 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070013172 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013173 else
13174 {
13175 /*Set the scan type to default type, in this case it is ACTIVE*/
13176 scanRequest.scanType = pScanInfo->scan_mode;
13177 }
13178 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
13179 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070013180
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013181 csr_scan_request_assign_bssid(&scanRequest, request);
13182
Jeff Johnson295189b2012-06-20 16:38:30 -070013183 /* set BSSType to default type */
13184 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
13185
13186 /*TODO: scan the requested channels only*/
13187
13188 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013189 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070013190 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013191 hddLog(VOS_TRACE_LEVEL_WARN,
13192 "No of Scan Channels exceeded limit: %d", request->n_channels);
13193 request->n_channels = MAX_CHANNEL;
13194 }
13195
13196 hddLog(VOS_TRACE_LEVEL_INFO,
13197 "No of Scan Channels: %d", request->n_channels);
13198
13199
13200 if( request->n_channels )
13201 {
13202 char chList [(request->n_channels*5)+1];
13203 int len;
13204 channelList = vos_mem_malloc( request->n_channels );
13205 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053013206 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013207 hddLog(VOS_TRACE_LEVEL_ERROR,
13208 "%s: memory alloc failed channelList", __func__);
13209 status = -ENOMEM;
13210 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053013211 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013212
13213 for( i = 0, len = 0; i < request->n_channels ; i++ )
13214 {
13215 channelList[i] = request->channels[i]->hw_value;
13216 len += snprintf(chList+len, 5, "%d ", channelList[i]);
13217 }
13218
Nirav Shah20ac06f2013-12-12 18:14:06 +053013219 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013220 "Channel-List: %s ", chList);
13221 }
c_hpothu53512302014-04-15 18:49:53 +053013222
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013223 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13224 scanRequest.ChannelInfo.ChannelList = channelList;
13225
13226 /* set requestType to full scan */
13227 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13228
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013229 /* if there is back to back scan happening in driver with in
13230 * nDeferScanTimeInterval interval driver should defer new scan request
13231 * and should provide last cached scan results instead of new channel list.
13232 * This rule is not applicable if scan is p2p scan.
13233 * This condition will work only in case when last request no of channels
13234 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013235 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013236 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013237 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013238
Sushant Kaushik86592172015-04-27 16:35:03 +053013239 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13240 /* if wps ie is NULL , then only defer scan */
13241 if ( pWpsIe == NULL &&
13242 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013243 {
13244 if ( pScanInfo->last_scan_timestamp !=0 &&
13245 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13246 {
13247 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13248 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13249 vos_mem_compare(pScanInfo->last_scan_channelList,
13250 channelList, pScanInfo->last_scan_numChannels))
13251 {
13252 hddLog(VOS_TRACE_LEVEL_WARN,
13253 " New and old station scan time differ is less then %u",
13254 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13255
13256 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013257 pAdapter);
13258
Agarwal Ashish57e84372014-12-05 18:26:53 +053013259 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013260 "Return old cached scan as all channels and no of channels are same");
13261
Agarwal Ashish57e84372014-12-05 18:26:53 +053013262 if (0 > ret)
13263 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013264
Agarwal Ashish57e84372014-12-05 18:26:53 +053013265 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013266
13267 status = eHAL_STATUS_SUCCESS;
13268 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013269 }
13270 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013271 }
13272
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013273 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13274 * search (Flush on both full scan and social scan but not on single
13275 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13276 */
13277
13278 /* Supplicant does single channel scan after 8-way handshake
13279 * and in that case driver shoudnt flush scan results. If
13280 * driver flushes the scan results here and unfortunately if
13281 * the AP doesnt respond to our probe req then association
13282 * fails which is not desired
13283 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013284 if ((request->n_ssids == 1)
13285 && (request->ssids != NULL)
13286 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13287 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013288
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013289 if( is_p2p_scan ||
13290 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013291 {
13292 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13293 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13294 pAdapter->sessionId );
13295 }
13296
13297 if( request->ie_len )
13298 {
13299 /* save this for future association (join requires this) */
13300 /*TODO: Array needs to be converted to dynamic allocation,
13301 * as multiple ie.s can be sent in cfg80211_scan_request structure
13302 * CR 597966
13303 */
13304 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13305 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13306 pScanInfo->scanAddIE.length = request->ie_len;
13307
13308 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13309 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13310 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013311 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013312 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013313 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013314 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13315 memcpy( pwextBuf->roamProfile.addIEScan,
13316 request->ie, request->ie_len);
13317 }
13318 else
13319 {
13320 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13321 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013322 }
13323
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013324 }
13325 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13326 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13327
13328 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13329 request->ie_len);
13330 if (pP2pIe != NULL)
13331 {
13332#ifdef WLAN_FEATURE_P2P_DEBUG
13333 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13334 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13335 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013336 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013337 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13338 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13339 "Go nego completed to Connection is started");
13340 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13341 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013342 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013343 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13344 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013345 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013346 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13347 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13348 "Disconnected state to Connection is started");
13349 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13350 "for 4way Handshake");
13351 }
13352#endif
13353
13354 /* no_cck will be set during p2p find to disable 11b rates */
13355 if(TRUE == request->no_cck)
13356 {
13357 hddLog(VOS_TRACE_LEVEL_INFO,
13358 "%s: This is a P2P Search", __func__);
13359 scanRequest.p2pSearch = 1;
13360
13361 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013362 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013363 /* set requestType to P2P Discovery */
13364 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13365 }
13366
13367 /*
13368 Skip Dfs Channel in case of P2P Search
13369 if it is set in ini file
13370 */
13371 if(cfg_param->skipDfsChnlInP2pSearch)
13372 {
13373 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013374 }
13375 else
13376 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013377 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013378 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013379
Agarwal Ashish4f616132013-12-30 23:32:50 +053013380 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013381 }
13382 }
13383
13384 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13385
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013386#ifdef FEATURE_WLAN_TDLS
13387 /* if tdls disagree scan right now, return immediately.
13388 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13389 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13390 */
13391 status = wlan_hdd_tdls_scan_callback (pAdapter,
13392 wiphy,
13393#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13394 dev,
13395#endif
13396 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013397 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013398 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053013399 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013400 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13401 "scan rejected %d", __func__, status);
13402 else
13403 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13404 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013405 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053013406 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013407 }
13408#endif
13409
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013410 /* acquire the wakelock to avoid the apps suspend during the scan. To
13411 * address the following issues.
13412 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13413 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13414 * for long time, this result in apps running at full power for long time.
13415 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13416 * be stuck in full power because of resume BMPS
13417 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013418 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013419
Nirav Shah20ac06f2013-12-12 18:14:06 +053013420 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13421 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013422 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13423 scanRequest.requestType, scanRequest.scanType,
13424 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013425 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13426
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013427 if (pHddCtx->spoofMacAddr.isEnabled &&
13428 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013429 {
13430 hddLog(VOS_TRACE_LEVEL_INFO,
13431 "%s: MAC Spoofing enabled for current scan", __func__);
13432 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13433 * to fill TxBds for probe request during current scan
13434 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013435 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013436 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013437
13438 if(status != VOS_STATUS_SUCCESS)
13439 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013440 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013441 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013442#ifdef FEATURE_WLAN_TDLS
13443 wlan_hdd_tdls_scan_done_callback(pAdapter);
13444#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013445 goto free_mem;
13446 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013447 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013448 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013449 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013450 pAdapter->sessionId, &scanRequest, &scanId,
13451 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013452
Jeff Johnson295189b2012-06-20 16:38:30 -070013453 if (eHAL_STATUS_SUCCESS != status)
13454 {
13455 hddLog(VOS_TRACE_LEVEL_ERROR,
13456 "%s: sme_ScanRequest returned error %d", __func__, status);
13457 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013458 if(eHAL_STATUS_RESOURCES == status)
13459 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013460 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13461 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013462 status = -EBUSY;
13463 } else {
13464 status = -EIO;
13465 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013466 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013467
13468#ifdef FEATURE_WLAN_TDLS
13469 wlan_hdd_tdls_scan_done_callback(pAdapter);
13470#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013471 goto free_mem;
13472 }
13473
13474 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013475 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013476 pAdapter->request = request;
13477 pScanInfo->scanId = scanId;
13478
13479 complete(&pScanInfo->scan_req_completion_event);
13480
13481free_mem:
13482 if( scanRequest.SSIDs.SSIDList )
13483 {
13484 vos_mem_free(scanRequest.SSIDs.SSIDList);
13485 }
13486
13487 if( channelList )
13488 vos_mem_free( channelList );
13489
13490 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013491 return status;
13492}
13493
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013494int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13495#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13496 struct net_device *dev,
13497#endif
13498 struct cfg80211_scan_request *request)
13499{
13500 int ret;
13501
13502 vos_ssr_protect(__func__);
13503 ret = __wlan_hdd_cfg80211_scan(wiphy,
13504#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13505 dev,
13506#endif
13507 request);
13508 vos_ssr_unprotect(__func__);
13509
13510 return ret;
13511}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013512
13513void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13514{
13515 v_U8_t iniDot11Mode =
13516 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13517 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13518
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013519 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13520 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013521 switch ( iniDot11Mode )
13522 {
13523 case eHDD_DOT11_MODE_AUTO:
13524 case eHDD_DOT11_MODE_11ac:
13525 case eHDD_DOT11_MODE_11ac_ONLY:
13526#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013527 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13528 sme_IsFeatureSupportedByFW(DOT11AC) )
13529 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13530 else
13531 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013532#else
13533 hddDot11Mode = eHDD_DOT11_MODE_11n;
13534#endif
13535 break;
13536 case eHDD_DOT11_MODE_11n:
13537 case eHDD_DOT11_MODE_11n_ONLY:
13538 hddDot11Mode = eHDD_DOT11_MODE_11n;
13539 break;
13540 default:
13541 hddDot11Mode = iniDot11Mode;
13542 break;
13543 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013544#ifdef WLAN_FEATURE_AP_HT40_24G
13545 if (operationChannel > SIR_11B_CHANNEL_END)
13546#endif
13547 {
13548 /* This call decides required channel bonding mode */
13549 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013550 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13551 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013552 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013553}
13554
Jeff Johnson295189b2012-06-20 16:38:30 -070013555/*
13556 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013557 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013558 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013559int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013560 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13561 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013562{
13563 int status = 0;
13564 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013565 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013566 v_U32_t roamId;
13567 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013568 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013569 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013570
13571 ENTER();
13572
13573 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013574 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13575
13576 status = wlan_hdd_validate_context(pHddCtx);
13577 if (status)
13578 {
Yue Mae36e3552014-03-05 17:06:20 -080013579 return status;
13580 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013581
Jeff Johnson295189b2012-06-20 16:38:30 -070013582 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13583 {
13584 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13585 return -EINVAL;
13586 }
13587
13588 pRoamProfile = &pWextState->roamProfile;
13589
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013590 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013591 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013592 hdd_station_ctx_t *pHddStaCtx;
13593 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013594
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013595 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13596
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013597 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013598 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13599 {
13600 /*QoS not enabled in cfg file*/
13601 pRoamProfile->uapsd_mask = 0;
13602 }
13603 else
13604 {
13605 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013606 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013607 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13608 }
13609
13610 pRoamProfile->SSIDs.numOfSSIDs = 1;
13611 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13612 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013613 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013614 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13615 ssid, ssid_len);
13616
13617 if (bssid)
13618 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013619 pValidBssid = bssid;
13620 }
13621 else if (bssid_hint)
13622 {
13623 pValidBssid = bssid_hint;
13624 }
13625 if (pValidBssid)
13626 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013627 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013628 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013629 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013630 /* Save BSSID in seperate variable as well, as RoamProfile
13631 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013632 case of join failure we should send valid BSSID to supplicant
13633 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013634 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013635 WNI_CFG_BSSID_LEN);
13636 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013637 else
13638 {
13639 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13640 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013641
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013642 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13643 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013644 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13645 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013646 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013647 /*set gen ie*/
13648 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13649 /*set auth*/
13650 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13651 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013652#ifdef FEATURE_WLAN_WAPI
13653 if (pAdapter->wapi_info.nWapiMode)
13654 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013655 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013656 switch (pAdapter->wapi_info.wapiAuthMode)
13657 {
13658 case WAPI_AUTH_MODE_PSK:
13659 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013660 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013661 pAdapter->wapi_info.wapiAuthMode);
13662 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13663 break;
13664 }
13665 case WAPI_AUTH_MODE_CERT:
13666 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013667 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013668 pAdapter->wapi_info.wapiAuthMode);
13669 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13670 break;
13671 }
13672 } // End of switch
13673 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13674 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13675 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013676 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013677 pRoamProfile->AuthType.numEntries = 1;
13678 pRoamProfile->EncryptionType.numEntries = 1;
13679 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13680 pRoamProfile->mcEncryptionType.numEntries = 1;
13681 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13682 }
13683 }
13684#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013685#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013686 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013687 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13688 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13689 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013690 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13691 sizeof (tSirGtkOffloadParams));
13692 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013693 }
13694#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013695 pRoamProfile->csrPersona = pAdapter->device_mode;
13696
Jeff Johnson32d95a32012-09-10 13:15:23 -070013697 if( operatingChannel )
13698 {
13699 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13700 pRoamProfile->ChannelInfo.numOfChannels = 1;
13701 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013702 else
13703 {
13704 pRoamProfile->ChannelInfo.ChannelList = NULL;
13705 pRoamProfile->ChannelInfo.numOfChannels = 0;
13706 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013707 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13708 {
13709 hdd_select_cbmode(pAdapter,operatingChannel);
13710 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013711
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013712 /*
13713 * Change conn_state to connecting before sme_RoamConnect(),
13714 * because sme_RoamConnect() has a direct path to call
13715 * hdd_smeRoamCallback(), which will change the conn_state
13716 * If direct path, conn_state will be accordingly changed
13717 * to NotConnected or Associated by either
13718 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13719 * in sme_RoamCallback()
13720 * if sme_RomConnect is to be queued,
13721 * Connecting state will remain until it is completed.
13722 * If connection state is not changed,
13723 * connection state will remain in eConnectionState_NotConnected state.
13724 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13725 * if conn state is eConnectionState_NotConnected.
13726 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13727 * informed of connect result indication which is an issue.
13728 */
13729
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013730 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13731 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013732 {
13733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013734 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013735 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13736 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013737 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013738 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013739 pAdapter->sessionId, pRoamProfile, &roamId);
13740
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013741 if ((eHAL_STATUS_SUCCESS != status) &&
13742 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13743 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013744
13745 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013746 hddLog(VOS_TRACE_LEVEL_ERROR,
13747 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13748 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013749 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013750 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013751 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013752 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013753
13754 pRoamProfile->ChannelInfo.ChannelList = NULL;
13755 pRoamProfile->ChannelInfo.numOfChannels = 0;
13756
Jeff Johnson295189b2012-06-20 16:38:30 -070013757 }
13758 else
13759 {
13760 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13761 return -EINVAL;
13762 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013763 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013764 return status;
13765}
13766
13767/*
13768 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
13769 * This function is used to set the authentication type (OPEN/SHARED).
13770 *
13771 */
13772static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
13773 enum nl80211_auth_type auth_type)
13774{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013775 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013776 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13777
13778 ENTER();
13779
13780 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013781 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070013782 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013783 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013784 hddLog(VOS_TRACE_LEVEL_INFO,
13785 "%s: set authentication type to AUTOSWITCH", __func__);
13786 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
13787 break;
13788
13789 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013790#ifdef WLAN_FEATURE_VOWIFI_11R
13791 case NL80211_AUTHTYPE_FT:
13792#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013793 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013794 "%s: set authentication type to OPEN", __func__);
13795 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
13796 break;
13797
13798 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013799 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013800 "%s: set authentication type to SHARED", __func__);
13801 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
13802 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013803#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013804 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013805 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013806 "%s: set authentication type to CCKM WPA", __func__);
13807 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
13808 break;
13809#endif
13810
13811
13812 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013813 hddLog(VOS_TRACE_LEVEL_ERROR,
13814 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013815 auth_type);
13816 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
13817 return -EINVAL;
13818 }
13819
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013820 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013821 pHddStaCtx->conn_info.authType;
13822 return 0;
13823}
13824
13825/*
13826 * FUNCTION: wlan_hdd_set_akm_suite
13827 * This function is used to set the key mgmt type(PSK/8021x).
13828 *
13829 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013830static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013831 u32 key_mgmt
13832 )
13833{
13834 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13835 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053013836 /* Should be in ieee802_11_defs.h */
13837#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
13838#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070013839 /*set key mgmt type*/
13840 switch(key_mgmt)
13841 {
13842 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053013843 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013844#ifdef WLAN_FEATURE_VOWIFI_11R
13845 case WLAN_AKM_SUITE_FT_PSK:
13846#endif
13847 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070013848 __func__);
13849 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
13850 break;
13851
13852 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053013853 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013854#ifdef WLAN_FEATURE_VOWIFI_11R
13855 case WLAN_AKM_SUITE_FT_8021X:
13856#endif
13857 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070013858 __func__);
13859 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13860 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013861#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013862#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
13863#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
13864 case WLAN_AKM_SUITE_CCKM:
13865 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
13866 __func__);
13867 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
13868 break;
13869#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070013870#ifndef WLAN_AKM_SUITE_OSEN
13871#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
13872 case WLAN_AKM_SUITE_OSEN:
13873 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
13874 __func__);
13875 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13876 break;
13877#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013878
13879 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013880 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013881 __func__, key_mgmt);
13882 return -EINVAL;
13883
13884 }
13885 return 0;
13886}
13887
13888/*
13889 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013890 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070013891 * (NONE/WEP40/WEP104/TKIP/CCMP).
13892 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013893static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
13894 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070013895 bool ucast
13896 )
13897{
13898 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013899 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013900 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13901
13902 ENTER();
13903
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013904 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013905 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013906 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070013907 __func__, cipher);
13908 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13909 }
13910 else
13911 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013912
Jeff Johnson295189b2012-06-20 16:38:30 -070013913 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013914 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013915 {
13916 case IW_AUTH_CIPHER_NONE:
13917 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13918 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013919
Jeff Johnson295189b2012-06-20 16:38:30 -070013920 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013921 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070013922 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013923
Jeff Johnson295189b2012-06-20 16:38:30 -070013924 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013925 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070013926 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013927
Jeff Johnson295189b2012-06-20 16:38:30 -070013928 case WLAN_CIPHER_SUITE_TKIP:
13929 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
13930 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013931
Jeff Johnson295189b2012-06-20 16:38:30 -070013932 case WLAN_CIPHER_SUITE_CCMP:
13933 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13934 break;
13935#ifdef FEATURE_WLAN_WAPI
13936 case WLAN_CIPHER_SUITE_SMS4:
13937 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
13938 break;
13939#endif
13940
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013941#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013942 case WLAN_CIPHER_SUITE_KRK:
13943 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
13944 break;
13945#endif
13946 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013947 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013948 __func__, cipher);
13949 return -EOPNOTSUPP;
13950 }
13951 }
13952
13953 if (ucast)
13954 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013955 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013956 __func__, encryptionType);
13957 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13958 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013959 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013960 encryptionType;
13961 }
13962 else
13963 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013964 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013965 __func__, encryptionType);
13966 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
13967 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
13968 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
13969 }
13970
13971 return 0;
13972}
13973
13974
13975/*
13976 * FUNCTION: wlan_hdd_cfg80211_set_ie
13977 * This function is used to parse WPA/RSN IE's.
13978 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013979int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013980#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13981 const u8 *ie,
13982#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013983 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013984#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013985 size_t ie_len
13986 )
13987{
13988 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013989#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13990 const u8 *genie = ie;
13991#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013992 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013993#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013994 v_U16_t remLen = ie_len;
13995#ifdef FEATURE_WLAN_WAPI
13996 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
13997 u16 *tmp;
13998 v_U16_t akmsuiteCount;
13999 int *akmlist;
14000#endif
14001 ENTER();
14002
14003 /* clear previous assocAddIE */
14004 pWextState->assocAddIE.length = 0;
14005 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014006 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014007
14008 while (remLen >= 2)
14009 {
14010 v_U16_t eLen = 0;
14011 v_U8_t elementId;
14012 elementId = *genie++;
14013 eLen = *genie++;
14014 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014015
Arif Hussain6d2a3322013-11-17 19:50:10 -080014016 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070014017 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014018
14019 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070014020 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014021 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014022 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 -070014023 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014024 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014025 "%s: Invalid WPA IE", __func__);
14026 return -EINVAL;
14027 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014028 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070014029 {
14030 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014031 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014032 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014033
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014034 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014035 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014036 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
14037 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014038 VOS_ASSERT(0);
14039 return -ENOMEM;
14040 }
14041 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14042 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14043 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014044
Jeff Johnson295189b2012-06-20 16:38:30 -070014045 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
14046 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14047 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14048 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014049 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
14050 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014051 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
14052 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14053 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
14054 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
14055 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
14056 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014057 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053014058 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070014059 {
14060 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014061 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014062 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014063
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014064 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014065 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014066 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14067 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014068 VOS_ASSERT(0);
14069 return -ENOMEM;
14070 }
14071 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14072 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14073 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014074
Jeff Johnson295189b2012-06-20 16:38:30 -070014075 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14076 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14077 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014078#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014079 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
14080 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014081 /*Consider WFD IE, only for P2P Client */
14082 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
14083 {
14084 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014085 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014086 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014087
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014088 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014089 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014090 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14091 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014092 VOS_ASSERT(0);
14093 return -ENOMEM;
14094 }
14095 // WFD IE is saved to Additional IE ; it should be accumulated to handle
14096 // WPS IE + P2P IE + WFD IE
14097 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14098 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014099
Jeff Johnson295189b2012-06-20 16:38:30 -070014100 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14101 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14102 }
14103#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014104 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014105 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014106 HS20_OUI_TYPE_SIZE)) )
14107 {
14108 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014109 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014110 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014111
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014112 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014113 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014114 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14115 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014116 VOS_ASSERT(0);
14117 return -ENOMEM;
14118 }
14119 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14120 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014121
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014122 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14123 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14124 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014125 /* Appending OSEN Information Element in Assiciation Request */
14126 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
14127 OSEN_OUI_TYPE_SIZE)) )
14128 {
14129 v_U16_t curAddIELen = pWextState->assocAddIE.length;
14130 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
14131 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014132
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014133 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014134 {
14135 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14136 "Need bigger buffer space");
14137 VOS_ASSERT(0);
14138 return -ENOMEM;
14139 }
14140 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14141 pWextState->assocAddIE.length += eLen + 2;
14142
14143 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
14144 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14145 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14146 }
14147
Abhishek Singh4322e622015-06-10 15:42:54 +053014148 /* Update only for WPA IE */
14149 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
14150 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014151
14152 /* populating as ADDIE in beacon frames */
14153 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014154 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014155 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
14156 {
14157 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14158 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
14159 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14160 {
14161 hddLog(LOGE,
14162 "Coldn't pass "
14163 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
14164 }
14165 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
14166 else
14167 hddLog(LOGE,
14168 "Could not pass on "
14169 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
14170
14171 /* IBSS mode doesn't contain params->proberesp_ies still
14172 beaconIE's need to be populated in probe response frames */
14173 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
14174 {
14175 u16 rem_probe_resp_ie_len = eLen + 2;
14176 u8 probe_rsp_ie_len[3] = {0};
14177 u8 counter = 0;
14178
14179 /* Check Probe Resp Length if it is greater then 255 then
14180 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
14181 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
14182 not able Store More then 255 bytes into One Variable */
14183
14184 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
14185 {
14186 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
14187 {
14188 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
14189 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
14190 }
14191 else
14192 {
14193 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
14194 rem_probe_resp_ie_len = 0;
14195 }
14196 }
14197
14198 rem_probe_resp_ie_len = 0;
14199
14200 if (probe_rsp_ie_len[0] > 0)
14201 {
14202 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14203 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
14204 (tANI_U8*)(genie - 2),
14205 probe_rsp_ie_len[0], NULL,
14206 eANI_BOOLEAN_FALSE)
14207 == eHAL_STATUS_FAILURE)
14208 {
14209 hddLog(LOGE,
14210 "Could not pass"
14211 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
14212 }
14213 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
14214 }
14215
14216 if (probe_rsp_ie_len[1] > 0)
14217 {
14218 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14219 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
14220 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14221 probe_rsp_ie_len[1], NULL,
14222 eANI_BOOLEAN_FALSE)
14223 == eHAL_STATUS_FAILURE)
14224 {
14225 hddLog(LOGE,
14226 "Could not pass"
14227 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14228 }
14229 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14230 }
14231
14232 if (probe_rsp_ie_len[2] > 0)
14233 {
14234 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14235 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14236 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14237 probe_rsp_ie_len[2], NULL,
14238 eANI_BOOLEAN_FALSE)
14239 == eHAL_STATUS_FAILURE)
14240 {
14241 hddLog(LOGE,
14242 "Could not pass"
14243 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14244 }
14245 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14246 }
14247
14248 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14249 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14250 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14251 {
14252 hddLog(LOGE,
14253 "Could not pass"
14254 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14255 }
14256 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014257 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014258 break;
14259 case DOT11F_EID_RSN:
14260 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14261 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14262 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14263 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14264 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14265 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014266
Abhishek Singhb16f3562016-01-20 11:08:32 +053014267 /* Appending extended capabilities with Interworking or
14268 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053014269 *
14270 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053014271 * interworkingService or bsstransition bit is set to 1.
14272 * Driver is only interested in interworkingService and
14273 * bsstransition capability from supplicant.
14274 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053014275 * required from supplicat, it needs to be handled while
14276 * sending Assoc Req in LIM.
14277 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014278 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014279 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014280 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014281 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014282 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014283
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014284 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014285 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014286 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14287 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014288 VOS_ASSERT(0);
14289 return -ENOMEM;
14290 }
14291 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14292 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014293
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014294 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14295 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14296 break;
14297 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014298#ifdef FEATURE_WLAN_WAPI
14299 case WLAN_EID_WAPI:
14300 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014301 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014302 pAdapter->wapi_info.nWapiMode);
14303 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014304 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014305 akmsuiteCount = WPA_GET_LE16(tmp);
14306 tmp = tmp + 1;
14307 akmlist = (int *)(tmp);
14308 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14309 {
14310 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14311 }
14312 else
14313 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014314 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014315 VOS_ASSERT(0);
14316 return -EINVAL;
14317 }
14318
14319 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14320 {
14321 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014322 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014323 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014324 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014325 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014326 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014327 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014328 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014329 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14330 }
14331 break;
14332#endif
14333 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014334 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014335 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014336 /* when Unknown IE is received we should break and continue
14337 * to the next IE in the buffer instead we were returning
14338 * so changing this to break */
14339 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014340 }
14341 genie += eLen;
14342 remLen -= eLen;
14343 }
14344 EXIT();
14345 return 0;
14346}
14347
14348/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014349 * FUNCTION: hdd_isWPAIEPresent
14350 * Parse the received IE to find the WPA IE
14351 *
14352 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014353static bool hdd_isWPAIEPresent(
14354#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14355 const u8 *ie,
14356#else
14357 u8 *ie,
14358#endif
14359 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014360{
14361 v_U8_t eLen = 0;
14362 v_U16_t remLen = ie_len;
14363 v_U8_t elementId = 0;
14364
14365 while (remLen >= 2)
14366 {
14367 elementId = *ie++;
14368 eLen = *ie++;
14369 remLen -= 2;
14370 if (eLen > remLen)
14371 {
14372 hddLog(VOS_TRACE_LEVEL_ERROR,
14373 "%s: IE length is wrong %d", __func__, eLen);
14374 return FALSE;
14375 }
14376 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14377 {
14378 /* OUI - 0x00 0X50 0XF2
14379 WPA Information Element - 0x01
14380 WPA version - 0x01*/
14381 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14382 return TRUE;
14383 }
14384 ie += eLen;
14385 remLen -= eLen;
14386 }
14387 return FALSE;
14388}
14389
14390/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014391 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014392 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014393 * parameters during connect operation.
14394 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014395int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014396 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014397 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014398{
14399 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014400 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014401 ENTER();
14402
14403 /*set wpa version*/
14404 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14405
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014406 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014407 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014408 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014409 {
14410 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14411 }
14412 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14413 {
14414 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14415 }
14416 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014417
14418 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014419 pWextState->wpaVersion);
14420
14421 /*set authentication type*/
14422 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14423
14424 if (0 > status)
14425 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014426 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014427 "%s: failed to set authentication type ", __func__);
14428 return status;
14429 }
14430
14431 /*set key mgmt type*/
14432 if (req->crypto.n_akm_suites)
14433 {
14434 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14435 if (0 > status)
14436 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014437 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014438 __func__);
14439 return status;
14440 }
14441 }
14442
14443 /*set pairwise cipher type*/
14444 if (req->crypto.n_ciphers_pairwise)
14445 {
14446 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14447 req->crypto.ciphers_pairwise[0], true);
14448 if (0 > status)
14449 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014450 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014451 "%s: failed to set unicast cipher type", __func__);
14452 return status;
14453 }
14454 }
14455 else
14456 {
14457 /*Reset previous cipher suite to none*/
14458 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14459 if (0 > status)
14460 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014461 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014462 "%s: failed to set unicast cipher type", __func__);
14463 return status;
14464 }
14465 }
14466
14467 /*set group cipher type*/
14468 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14469 false);
14470
14471 if (0 > status)
14472 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014473 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014474 __func__);
14475 return status;
14476 }
14477
Chet Lanctot186b5732013-03-18 10:26:30 -070014478#ifdef WLAN_FEATURE_11W
14479 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14480#endif
14481
Jeff Johnson295189b2012-06-20 16:38:30 -070014482 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14483 if (req->ie_len)
14484 {
14485 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14486 if ( 0 > status)
14487 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014488 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014489 __func__);
14490 return status;
14491 }
14492 }
14493
14494 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014495 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014496 {
14497 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14498 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14499 )
14500 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014501 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014502 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14503 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014504 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014505 __func__);
14506 return -EOPNOTSUPP;
14507 }
14508 else
14509 {
14510 u8 key_len = req->key_len;
14511 u8 key_idx = req->key_idx;
14512
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014513 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014514 && (CSR_MAX_NUM_KEY > key_idx)
14515 )
14516 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014517 hddLog(VOS_TRACE_LEVEL_INFO,
14518 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014519 __func__, key_idx, key_len);
14520 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014521 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014522 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014523 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014524 (u8)key_len;
14525 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14526 }
14527 }
14528 }
14529 }
14530
14531 return status;
14532}
14533
14534/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014535 * FUNCTION: wlan_hdd_try_disconnect
14536 * This function is used to disconnect from previous
14537 * connection
14538 */
14539static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14540{
14541 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014542 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014543 hdd_station_ctx_t *pHddStaCtx;
14544 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014545 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014546
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014547 ret = wlan_hdd_validate_context(pHddCtx);
14548 if (0 != ret)
14549 {
14550 return ret;
14551 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014552 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14553
14554 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14555
14556 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14557 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053014558 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014559 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14560 {
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014561 spin_lock_bh(&pAdapter->lock_for_active_session);
14562 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14563 {
14564 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14565 }
14566 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053014567 hdd_connSetConnectionState(pHddStaCtx,
14568 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014569 /* Issue disconnect to CSR */
14570 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014571 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014572 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014573 eCSR_DISCONNECT_REASON_UNSPECIFIED);
14574 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
14575 hddLog(LOG1,
14576 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
14577 } else if ( 0 != status ) {
14578 hddLog(LOGE,
14579 FL("csrRoamDisconnect failure, returned %d"),
14580 (int)status );
14581 result = -EINVAL;
14582 goto disconnected;
14583 }
14584 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014585 &pAdapter->disconnect_comp_var,
14586 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014587 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
14588 hddLog(LOGE,
14589 "%s: Failed to disconnect, timed out", __func__);
14590 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014591 }
14592 }
14593 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14594 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014595 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014596 &pAdapter->disconnect_comp_var,
14597 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014598 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014599 {
14600 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014601 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014602 }
14603 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014604disconnected:
14605 hddLog(LOG1,
14606 FL("Set HDD connState to eConnectionState_NotConnected"));
14607 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14608 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014609}
14610
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014611/**
14612 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
14613 * @adapter: Pointer to the HDD adapter
14614 * @req: Pointer to the structure cfg_connect_params receieved from user space
14615 *
14616 * This function will start reassociation if bssid hint, channel hint and
14617 * previous bssid parameters are present in the connect request
14618 *
14619 * Return: success if reassociation is happening
14620 * Error code if reassociation is not permitted or not happening
14621 */
14622#ifdef CFG80211_CONNECT_PREV_BSSID
14623static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14624 struct cfg80211_connect_params *req)
14625{
14626 int status = -EPERM;
14627 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
14628 hddLog(VOS_TRACE_LEVEL_INFO,
14629 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
14630 req->channel_hint->hw_value,
14631 MAC_ADDR_ARRAY(req->bssid_hint));
14632 status = hdd_reassoc(adapter, req->bssid_hint,
14633 req->channel_hint->hw_value,
14634 CONNECT_CMD_USERSPACE);
14635 }
14636 return status;
14637}
14638#else
14639static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14640 struct cfg80211_connect_params *req)
14641{
14642 return -EPERM;
14643}
14644#endif
14645
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014646/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014647 * FUNCTION: __wlan_hdd_cfg80211_connect
14648 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014649 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014650static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014651 struct net_device *ndev,
14652 struct cfg80211_connect_params *req
14653 )
14654{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014655 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014656 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053014657#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
14658 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014659 const u8 *bssid_hint = req->bssid_hint;
14660#else
14661 const u8 *bssid_hint = NULL;
14662#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014663 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014664 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014665 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014666
14667 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014668
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014669 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14670 TRACE_CODE_HDD_CFG80211_CONNECT,
14671 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014672 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014673 "%s: device_mode = %s (%d)", __func__,
14674 hdd_device_modetoString(pAdapter->device_mode),
14675 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014676
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014677 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014678 if (!pHddCtx)
14679 {
14680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14681 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014682 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014683 }
14684
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014685 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014686 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014687 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014688 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014689 }
14690
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014691 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
14692 if (0 == status)
14693 return status;
14694
Agarwal Ashish51325b52014-06-16 16:50:49 +053014695
Jeff Johnson295189b2012-06-20 16:38:30 -070014696#ifdef WLAN_BTAMP_FEATURE
14697 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014698 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014699 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014700 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014701 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014702 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014703 }
14704#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014705
14706 //If Device Mode is Station Concurrent Sessions Exit BMps
14707 //P2P Mode will be taken care in Open/close adapter
14708 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014709 (vos_concurrent_open_sessions_running())) {
14710 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14711 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014712 }
14713
14714 /*Try disconnecting if already in connected state*/
14715 status = wlan_hdd_try_disconnect(pAdapter);
14716 if ( 0 > status)
14717 {
14718 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14719 " connection"));
14720 return -EALREADY;
14721 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053014722 /* Check for max concurrent connections after doing disconnect if any*/
14723 if (vos_max_concurrent_connections_reached()) {
14724 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14725 return -ECONNREFUSED;
14726 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014727
Jeff Johnson295189b2012-06-20 16:38:30 -070014728 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014729 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014730
14731 if ( 0 > status)
14732 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014733 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014734 __func__);
14735 return status;
14736 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053014737
14738 if (pHddCtx->spoofMacAddr.isEnabled)
14739 {
14740 hddLog(VOS_TRACE_LEVEL_INFO,
14741 "%s: MAC Spoofing enabled ", __func__);
14742 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14743 * to fill TxBds for probe request during SSID scan which may happen
14744 * as part of connect command
14745 */
14746 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
14747 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
14748 if (status != VOS_STATUS_SUCCESS)
14749 return -ECONNREFUSED;
14750 }
14751
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014752 if (req->channel)
14753 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070014754 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014755 channel = 0;
14756 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14757 req->ssid_len, req->bssid,
14758 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014759
Sushant Kaushikd7083982015-03-18 14:33:24 +053014760 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014761 {
14762 //ReEnable BMPS if disabled
14763 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
14764 (NULL != pHddCtx))
14765 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053014766 if (pHddCtx->hdd_wlan_suspended)
14767 {
14768 hdd_set_pwrparams(pHddCtx);
14769 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014770 //ReEnable Bmps and Imps back
14771 hdd_enable_bmps_imps(pHddCtx);
14772 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014773 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070014774 return status;
14775 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014776 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014777 EXIT();
14778 return status;
14779}
14780
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014781static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
14782 struct net_device *ndev,
14783 struct cfg80211_connect_params *req)
14784{
14785 int ret;
14786 vos_ssr_protect(__func__);
14787 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
14788 vos_ssr_unprotect(__func__);
14789
14790 return ret;
14791}
Jeff Johnson295189b2012-06-20 16:38:30 -070014792
14793/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014794 * FUNCTION: wlan_hdd_disconnect
14795 * This function is used to issue a disconnect request to SME
14796 */
14797int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
14798{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014799 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014800 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014801 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014802 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014803
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014804 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014805
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014806 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014807 if (0 != status)
14808 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014809 return status;
14810 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053014811 /* Indicate sme of disconnect so that in progress connection or preauth
14812 * can be aborted
14813 */
14814 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053014815 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014816 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014817
Agarwal Ashish47d18112014-08-04 19:55:07 +053014818 /* Need to apply spin lock before decreasing active sessions
14819 * as there can be chance for double decrement if context switch
14820 * Calls hdd_DisConnectHandler.
14821 */
14822
14823 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014824 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14825 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014826 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14827 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053014828 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
14829 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014830
Abhishek Singhf4669da2014-05-26 15:07:49 +053014831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053014832 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
14833
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014834 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014835
Mihir Shete182a0b22014-08-18 16:08:48 +053014836 /*
14837 * stop tx queues before deleting STA/BSS context from the firmware.
14838 * tx has to be disabled because the firmware can get busy dropping
14839 * the tx frames after BSS/STA has been deleted and will not send
14840 * back a response resulting in WDI timeout
14841 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053014842 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053014843 netif_tx_disable(pAdapter->dev);
14844 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014845
Mihir Shete182a0b22014-08-18 16:08:48 +053014846 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014847 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14848 pAdapter->sessionId, reason);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014849 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
14850 {
14851 hddLog(LOG1,
14852 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014853 }
14854 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014855 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014856 hddLog(LOGE,
14857 FL("csrRoamDisconnect failure, returned %d"),
14858 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014859 result = -EINVAL;
14860 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014861 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014862 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014863 &pAdapter->disconnect_comp_var,
14864 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014865 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014866 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014867 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014868 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014869 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014870 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014871disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014872 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014873 FL("Set HDD connState to eConnectionState_NotConnected"));
14874 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053014875#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
14876 /* Sending disconnect event to userspace for kernel version < 3.11
14877 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
14878 */
14879 hddLog(LOG1, FL("Send disconnected event to userspace"));
14880
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053014881 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053014882 WLAN_REASON_UNSPECIFIED);
14883#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014884
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014885 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014886 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014887}
14888
14889
14890/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014891 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070014892 * This function is used to issue a disconnect request to SME
14893 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014894static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014895 struct net_device *dev,
14896 u16 reason
14897 )
14898{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014899 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014900 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014901 tCsrRoamProfile *pRoamProfile;
14902 hdd_station_ctx_t *pHddStaCtx;
14903 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014904#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014905 tANI_U8 staIdx;
14906#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014907
Jeff Johnson295189b2012-06-20 16:38:30 -070014908 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014909
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014910 if (!pAdapter) {
14911 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14912 return -EINVAL;
14913 }
14914
14915 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14916 if (!pHddStaCtx) {
14917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
14918 return -EINVAL;
14919 }
14920
14921 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14922 status = wlan_hdd_validate_context(pHddCtx);
14923 if (0 != status)
14924 {
14925 return status;
14926 }
14927
14928 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
14929
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014930 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14931 TRACE_CODE_HDD_CFG80211_DISCONNECT,
14932 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014933 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
14934 __func__, hdd_device_modetoString(pAdapter->device_mode),
14935 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014936
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014937 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
14938 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070014939
Jeff Johnson295189b2012-06-20 16:38:30 -070014940 if (NULL != pRoamProfile)
14941 {
14942 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014943 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
14944 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070014945 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014946 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070014947 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014948 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014949 switch(reason)
14950 {
14951 case WLAN_REASON_MIC_FAILURE:
14952 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
14953 break;
14954
14955 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
14956 case WLAN_REASON_DISASSOC_AP_BUSY:
14957 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
14958 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
14959 break;
14960
14961 case WLAN_REASON_PREV_AUTH_NOT_VALID:
14962 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053014963 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070014964 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
14965 break;
14966
Jeff Johnson295189b2012-06-20 16:38:30 -070014967 default:
14968 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
14969 break;
14970 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014971 pScanInfo = &pHddCtx->scan_info;
14972 if (pScanInfo->mScanPending)
14973 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014974 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014975 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014976 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014977 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014978 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053014979 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014980#ifdef FEATURE_WLAN_TDLS
14981 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014982 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014983 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014984 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
14985 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014986 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014987 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014988 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014990 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014991 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014992 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014993 status = sme_DeleteTdlsPeerSta(
14994 WLAN_HDD_GET_HAL_CTX(pAdapter),
14995 pAdapter->sessionId,
14996 mac);
14997 if (status != eHAL_STATUS_SUCCESS) {
14998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
14999 return -EPERM;
15000 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015001 }
15002 }
15003#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015004 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015005 status = wlan_hdd_disconnect(pAdapter, reasonCode);
15006 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070015007 {
15008 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015009 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015010 __func__, (int)status );
15011 return -EINVAL;
15012 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015013 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015014 else
15015 {
15016 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
15017 "called while in %d state", __func__,
15018 pHddStaCtx->conn_info.connState);
15019 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015020 }
15021 else
15022 {
15023 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
15024 }
15025
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015026 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015027 return status;
15028}
15029
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015030static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
15031 struct net_device *dev,
15032 u16 reason
15033 )
15034{
15035 int ret;
15036 vos_ssr_protect(__func__);
15037 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
15038 vos_ssr_unprotect(__func__);
15039
15040 return ret;
15041}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015042
Jeff Johnson295189b2012-06-20 16:38:30 -070015043/*
15044 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015045 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015046 * settings in IBSS mode.
15047 */
15048static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015049 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015050 struct cfg80211_ibss_params *params
15051 )
15052{
15053 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015054 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015055 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15056 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015057
Jeff Johnson295189b2012-06-20 16:38:30 -070015058 ENTER();
15059
15060 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070015061 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070015062
15063 if (params->ie_len && ( NULL != params->ie) )
15064 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015065 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15066 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015067 {
15068 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15069 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15070 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015071 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015072 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015073 tDot11fIEWPA dot11WPAIE;
15074 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015075 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015076
Wilson Yang00256342013-10-10 23:13:38 -070015077 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015078 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15079 params->ie_len, DOT11F_EID_WPA);
15080 if ( NULL != ie )
15081 {
15082 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15083 // Unpack the WPA IE
15084 //Skip past the EID byte and length byte - and four byte WiFi OUI
15085 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
15086 &ie[2+4],
15087 ie[1] - 4,
15088 &dot11WPAIE);
15089 /*Extract the multicast cipher, the encType for unicast
15090 cipher for wpa-none is none*/
15091 encryptionType =
15092 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
15093 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015094 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015095
Jeff Johnson295189b2012-06-20 16:38:30 -070015096 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
15097
15098 if (0 > status)
15099 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015100 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015101 __func__);
15102 return status;
15103 }
15104 }
15105
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015106 pWextState->roamProfile.AuthType.authType[0] =
15107 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070015108 eCSR_AUTH_TYPE_OPEN_SYSTEM;
15109
15110 if (params->privacy)
15111 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015112 /* Security enabled IBSS, At this time there is no information available
15113 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070015114 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015115 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070015116 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015117 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070015118 *enable privacy bit in beacons */
15119
15120 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
15121 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015122 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
15123 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070015124 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15125 pWextState->roamProfile.EncryptionType.numEntries = 1;
15126 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070015127 return status;
15128}
15129
15130/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015131 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015132 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015133 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015134static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015135 struct net_device *dev,
15136 struct cfg80211_ibss_params *params
15137 )
15138{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015139 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015140 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15141 tCsrRoamProfile *pRoamProfile;
15142 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015143 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15144 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015145 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070015146
15147 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015148
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015149 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15150 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
15151 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015152 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015153 "%s: device_mode = %s (%d)", __func__,
15154 hdd_device_modetoString(pAdapter->device_mode),
15155 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015156
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015157 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015158 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015159 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015160 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015161 }
15162
15163 if (NULL == pWextState)
15164 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015165 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015166 __func__);
15167 return -EIO;
15168 }
15169
Agarwal Ashish51325b52014-06-16 16:50:49 +053015170 if (vos_max_concurrent_connections_reached()) {
15171 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15172 return -ECONNREFUSED;
15173 }
15174
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015175 /*Try disconnecting if already in connected state*/
15176 status = wlan_hdd_try_disconnect(pAdapter);
15177 if ( 0 > status)
15178 {
15179 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15180 " IBSS connection"));
15181 return -EALREADY;
15182 }
15183
Jeff Johnson295189b2012-06-20 16:38:30 -070015184 pRoamProfile = &pWextState->roamProfile;
15185
15186 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
15187 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015188 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015189 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015190 return -EINVAL;
15191 }
15192
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015193 /* BSSID is provided by upper layers hence no need to AUTO generate */
15194 if (NULL != params->bssid) {
15195 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15196 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
15197 hddLog (VOS_TRACE_LEVEL_ERROR,
15198 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15199 return -EIO;
15200 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015201 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015202 }
krunal sonie9002db2013-11-25 14:24:17 -080015203 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
15204 {
15205 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15206 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
15207 {
15208 hddLog (VOS_TRACE_LEVEL_ERROR,
15209 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15210 return -EIO;
15211 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015212
15213 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080015214 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015215 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080015216 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015217
Jeff Johnson295189b2012-06-20 16:38:30 -070015218 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070015219 if (NULL !=
15220#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15221 params->chandef.chan)
15222#else
15223 params->channel)
15224#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015225 {
15226 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015227 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15228 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
15229 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15230 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015231
15232 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015233 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070015234 ieee80211_frequency_to_channel(
15235#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15236 params->chandef.chan->center_freq);
15237#else
15238 params->channel->center_freq);
15239#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015240
15241 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15242 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070015243 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015244 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
15245 __func__);
15246 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070015247 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015248
15249 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015250 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015251 if (channelNum == validChan[indx])
15252 {
15253 break;
15254 }
15255 }
15256 if (indx >= numChans)
15257 {
15258 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015259 __func__, channelNum);
15260 return -EINVAL;
15261 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015262 /* Set the Operational Channel */
15263 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
15264 channelNum);
15265 pRoamProfile->ChannelInfo.numOfChannels = 1;
15266 pHddStaCtx->conn_info.operationChannel = channelNum;
15267 pRoamProfile->ChannelInfo.ChannelList =
15268 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070015269 }
15270
15271 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015272 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070015273 if (status < 0)
15274 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015275 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070015276 __func__);
15277 return status;
15278 }
15279
15280 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015281 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053015282 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015283 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015284
15285 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015286 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015287
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015288 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015289 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015290}
15291
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015292static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
15293 struct net_device *dev,
15294 struct cfg80211_ibss_params *params
15295 )
15296{
15297 int ret = 0;
15298
15299 vos_ssr_protect(__func__);
15300 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15301 vos_ssr_unprotect(__func__);
15302
15303 return ret;
15304}
15305
Jeff Johnson295189b2012-06-20 16:38:30 -070015306/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015307 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015308 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015309 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015310static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015311 struct net_device *dev
15312 )
15313{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015314 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015315 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15316 tCsrRoamProfile *pRoamProfile;
15317 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015318 int status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015319#ifdef WLAN_FEATURE_RMC
15320 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
15321#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015322
15323 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015324
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015325 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15326 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15327 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015328 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015329 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015330 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015331 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015332 }
15333
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015334 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15335 hdd_device_modetoString(pAdapter->device_mode),
15336 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015337 if (NULL == pWextState)
15338 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015339 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015340 __func__);
15341 return -EIO;
15342 }
15343
15344 pRoamProfile = &pWextState->roamProfile;
15345
15346 /* Issue disconnect only if interface type is set to IBSS */
15347 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15348 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015349 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015350 __func__);
15351 return -EINVAL;
15352 }
15353
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015354#ifdef WLAN_FEATURE_RMC
15355 /* Clearing add IE of beacon */
15356 if (ccmCfgSetStr(pHddCtx->hHal,
15357 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
15358 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
15359 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15360 {
15361 hddLog (VOS_TRACE_LEVEL_ERROR,
15362 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
15363 return -EINVAL;
15364 }
15365 if (ccmCfgSetInt(pHddCtx->hHal,
15366 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
15367 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15368 {
15369 hddLog (VOS_TRACE_LEVEL_ERROR,
15370 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
15371 __func__);
15372 return -EINVAL;
15373 }
15374
15375 // Reset WNI_CFG_PROBE_RSP Flags
15376 wlan_hdd_reset_prob_rspies(pAdapter);
15377
15378 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15379 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
15380 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15381 {
15382 hddLog (VOS_TRACE_LEVEL_ERROR,
15383 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
15384 __func__);
15385 return -EINVAL;
15386 }
15387#endif
15388
Jeff Johnson295189b2012-06-20 16:38:30 -070015389 /* Issue Disconnect request */
15390 INIT_COMPLETION(pAdapter->disconnect_comp_var);
15391 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15392 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15393
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015394 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015395 return 0;
15396}
15397
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015398static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15399 struct net_device *dev
15400 )
15401{
15402 int ret = 0;
15403
15404 vos_ssr_protect(__func__);
15405 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15406 vos_ssr_unprotect(__func__);
15407
15408 return ret;
15409}
15410
Jeff Johnson295189b2012-06-20 16:38:30 -070015411/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015412 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015413 * This function is used to set the phy parameters
15414 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15415 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015416static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015417 u32 changed)
15418{
15419 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15420 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015421 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015422
15423 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015424
15425 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015426 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15427 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015428
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015429 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015430 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015431 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015432 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015433 }
15434
Jeff Johnson295189b2012-06-20 16:38:30 -070015435 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15436 {
15437 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15438 WNI_CFG_RTS_THRESHOLD_STAMAX :
15439 wiphy->rts_threshold;
15440
15441 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015442 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015443 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015444 hddLog(VOS_TRACE_LEVEL_ERROR,
15445 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015446 __func__, rts_threshold);
15447 return -EINVAL;
15448 }
15449
15450 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15451 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015452 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015453 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015454 hddLog(VOS_TRACE_LEVEL_ERROR,
15455 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015456 __func__, rts_threshold);
15457 return -EIO;
15458 }
15459
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015460 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015461 rts_threshold);
15462 }
15463
15464 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15465 {
15466 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15467 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15468 wiphy->frag_threshold;
15469
15470 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015471 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015472 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015473 hddLog(VOS_TRACE_LEVEL_ERROR,
15474 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015475 frag_threshold);
15476 return -EINVAL;
15477 }
15478
15479 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15480 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015481 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015482 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015483 hddLog(VOS_TRACE_LEVEL_ERROR,
15484 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015485 __func__, frag_threshold);
15486 return -EIO;
15487 }
15488
15489 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15490 frag_threshold);
15491 }
15492
15493 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15494 || (changed & WIPHY_PARAM_RETRY_LONG))
15495 {
15496 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15497 wiphy->retry_short :
15498 wiphy->retry_long;
15499
15500 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15501 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15502 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015503 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015504 __func__, retry_value);
15505 return -EINVAL;
15506 }
15507
15508 if (changed & WIPHY_PARAM_RETRY_SHORT)
15509 {
15510 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15511 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015512 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015513 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015514 hddLog(VOS_TRACE_LEVEL_ERROR,
15515 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015516 __func__, retry_value);
15517 return -EIO;
15518 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015519 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015520 __func__, retry_value);
15521 }
15522 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15523 {
15524 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15525 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015526 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015527 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015528 hddLog(VOS_TRACE_LEVEL_ERROR,
15529 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015530 __func__, retry_value);
15531 return -EIO;
15532 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015533 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015534 __func__, retry_value);
15535 }
15536 }
15537
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015538 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015539 return 0;
15540}
15541
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015542static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15543 u32 changed)
15544{
15545 int ret;
15546
15547 vos_ssr_protect(__func__);
15548 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15549 vos_ssr_unprotect(__func__);
15550
15551 return ret;
15552}
15553
Jeff Johnson295189b2012-06-20 16:38:30 -070015554/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015555 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015556 * This function is used to set the txpower
15557 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015558static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015559#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15560 struct wireless_dev *wdev,
15561#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015562#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015563 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015564#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015565 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015566#endif
15567 int dbm)
15568{
15569 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015570 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015571 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15572 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015573 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015574
15575 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015576
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015577 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15578 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15579 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015580 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015581 if (0 != status)
15582 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015583 return status;
15584 }
15585
15586 hHal = pHddCtx->hHal;
15587
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015588 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15589 dbm, ccmCfgSetCallback,
15590 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015591 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015592 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015593 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15594 return -EIO;
15595 }
15596
15597 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15598 dbm);
15599
15600 switch(type)
15601 {
15602 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15603 /* Fall through */
15604 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15605 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15606 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015607 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15608 __func__);
15609 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015610 }
15611 break;
15612 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015613 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015614 __func__);
15615 return -EOPNOTSUPP;
15616 break;
15617 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015618 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15619 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015620 return -EIO;
15621 }
15622
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015623 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015624 return 0;
15625}
15626
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015627static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15628#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15629 struct wireless_dev *wdev,
15630#endif
15631#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15632 enum tx_power_setting type,
15633#else
15634 enum nl80211_tx_power_setting type,
15635#endif
15636 int dbm)
15637{
15638 int ret;
15639 vos_ssr_protect(__func__);
15640 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15641#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15642 wdev,
15643#endif
15644#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15645 type,
15646#else
15647 type,
15648#endif
15649 dbm);
15650 vos_ssr_unprotect(__func__);
15651
15652 return ret;
15653}
15654
Jeff Johnson295189b2012-06-20 16:38:30 -070015655/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015656 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015657 * This function is used to read the txpower
15658 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015659static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015660#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15661 struct wireless_dev *wdev,
15662#endif
15663 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015664{
15665
15666 hdd_adapter_t *pAdapter;
15667 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015668 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015669
Jeff Johnsone7245742012-09-05 17:12:55 -070015670 ENTER();
15671
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015672 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015673 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015674 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015675 *dbm = 0;
15676 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015677 }
15678
Jeff Johnson295189b2012-06-20 16:38:30 -070015679 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15680 if (NULL == pAdapter)
15681 {
15682 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15683 return -ENOENT;
15684 }
15685
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015686 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15687 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15688 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015689 wlan_hdd_get_classAstats(pAdapter);
15690 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15691
Jeff Johnsone7245742012-09-05 17:12:55 -070015692 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015693 return 0;
15694}
15695
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015696static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15697#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15698 struct wireless_dev *wdev,
15699#endif
15700 int *dbm)
15701{
15702 int ret;
15703
15704 vos_ssr_protect(__func__);
15705 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15706#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15707 wdev,
15708#endif
15709 dbm);
15710 vos_ssr_unprotect(__func__);
15711
15712 return ret;
15713}
15714
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015715static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015716#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15717 const u8* mac,
15718#else
15719 u8* mac,
15720#endif
15721 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015722{
15723 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15724 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15725 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053015726 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015727
15728 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
15729 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070015730
15731 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
15732 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
15733 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
15734 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
15735 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
15736 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
15737 tANI_U16 maxRate = 0;
15738 tANI_U16 myRate;
15739 tANI_U16 currentRate = 0;
15740 tANI_U8 maxSpeedMCS = 0;
15741 tANI_U8 maxMCSIdx = 0;
15742 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053015743 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070015744 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015745 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015746
Leo Chang6f8870f2013-03-26 18:11:36 -070015747#ifdef WLAN_FEATURE_11AC
15748 tANI_U32 vht_mcs_map;
15749 eDataRate11ACMaxMcs vhtMaxMcs;
15750#endif /* WLAN_FEATURE_11AC */
15751
Jeff Johnsone7245742012-09-05 17:12:55 -070015752 ENTER();
15753
Jeff Johnson295189b2012-06-20 16:38:30 -070015754 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15755 (0 == ssidlen))
15756 {
15757 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
15758 " Invalid ssidlen, %d", __func__, ssidlen);
15759 /*To keep GUI happy*/
15760 return 0;
15761 }
15762
Mukul Sharma811205f2014-07-09 21:07:30 +053015763 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
15764 {
15765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15766 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053015767 /* return a cached value */
15768 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053015769 return 0;
15770 }
15771
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015772 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015773 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015774 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015775 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015776 }
15777
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053015778 wlan_hdd_get_station_stats(pAdapter);
15779 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015780
Kiet Lam3b17fc82013-09-27 05:24:08 +053015781 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
15782 sinfo->filled |= STATION_INFO_SIGNAL;
15783
c_hpothu09f19542014-05-30 21:53:31 +053015784 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053015785 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
15786 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053015787 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053015788 {
15789 rate_flags = pAdapter->maxRateFlags;
15790 }
c_hpothu44ff4e02014-05-08 00:13:57 +053015791
Jeff Johnson295189b2012-06-20 16:38:30 -070015792 //convert to the UI units of 100kbps
15793 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
15794
15795#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070015796 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 -070015797 sinfo->signal,
15798 pCfg->reportMaxLinkSpeed,
15799 myRate,
15800 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015801 (int) pCfg->linkSpeedRssiMid,
15802 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070015803 (int) rate_flags,
15804 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070015805#endif //LINKSPEED_DEBUG_ENABLED
15806
15807 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
15808 {
15809 // we do not want to necessarily report the current speed
15810 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
15811 {
15812 // report the max possible speed
15813 rssidx = 0;
15814 }
15815 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
15816 {
15817 // report the max possible speed with RSSI scaling
15818 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
15819 {
15820 // report the max possible speed
15821 rssidx = 0;
15822 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015823 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070015824 {
15825 // report middle speed
15826 rssidx = 1;
15827 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015828 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
15829 {
15830 // report middle speed
15831 rssidx = 2;
15832 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015833 else
15834 {
15835 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015836 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070015837 }
15838 }
15839 else
15840 {
15841 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
15842 hddLog(VOS_TRACE_LEVEL_ERROR,
15843 "%s: Invalid value for reportMaxLinkSpeed: %u",
15844 __func__, pCfg->reportMaxLinkSpeed);
15845 rssidx = 0;
15846 }
15847
15848 maxRate = 0;
15849
15850 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015851 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
15852 OperationalRates, &ORLeng))
15853 {
15854 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15855 /*To keep GUI happy*/
15856 return 0;
15857 }
15858
Jeff Johnson295189b2012-06-20 16:38:30 -070015859 for (i = 0; i < ORLeng; i++)
15860 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015861 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015862 {
15863 /* Validate Rate Set */
15864 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
15865 {
15866 currentRate = supported_data_rate[j].supported_rate[rssidx];
15867 break;
15868 }
15869 }
15870 /* Update MAX rate */
15871 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15872 }
15873
15874 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015875 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
15876 ExtendedRates, &ERLeng))
15877 {
15878 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15879 /*To keep GUI happy*/
15880 return 0;
15881 }
15882
Jeff Johnson295189b2012-06-20 16:38:30 -070015883 for (i = 0; i < ERLeng; i++)
15884 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015885 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015886 {
15887 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
15888 {
15889 currentRate = supported_data_rate[j].supported_rate[rssidx];
15890 break;
15891 }
15892 }
15893 /* Update MAX rate */
15894 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15895 }
c_hpothu79aab322014-07-14 21:11:01 +053015896
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015897 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053015898 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015899 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053015900 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070015901 {
c_hpothu79aab322014-07-14 21:11:01 +053015902 if (rate_flags & eHAL_TX_RATE_VHT80)
15903 mode = 2;
15904 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
15905 mode = 1;
15906 else
15907 mode = 0;
15908
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015909 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
15910 MCSRates, &MCSLeng))
15911 {
15912 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15913 /*To keep GUI happy*/
15914 return 0;
15915 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015916 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070015917#ifdef WLAN_FEATURE_11AC
15918 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015919 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070015920 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015921 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015922 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070015923 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070015924 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015925 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015926 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015927 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070015928 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015929 maxMCSIdx = 7;
15930 }
15931 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
15932 {
15933 maxMCSIdx = 8;
15934 }
15935 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
15936 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015937 //VHT20 is supporting 0~8
15938 if (rate_flags & eHAL_TX_RATE_VHT20)
15939 maxMCSIdx = 8;
15940 else
15941 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070015942 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015943
c_hpothu79aab322014-07-14 21:11:01 +053015944 if (0 != rssidx)/*check for scaled */
15945 {
15946 //get middle rate MCS index if rssi=1/2
15947 for (i=0; i <= maxMCSIdx; i++)
15948 {
15949 if (sinfo->signal <= rssiMcsTbl[mode][i])
15950 {
15951 maxMCSIdx = i;
15952 break;
15953 }
15954 }
15955 }
15956
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015957 if (rate_flags & eHAL_TX_RATE_VHT80)
15958 {
15959 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
15960 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
15961 }
15962 else if (rate_flags & eHAL_TX_RATE_VHT40)
15963 {
15964 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
15965 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
15966 }
15967 else if (rate_flags & eHAL_TX_RATE_VHT20)
15968 {
15969 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
15970 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
15971 }
15972
Leo Chang6f8870f2013-03-26 18:11:36 -070015973 maxSpeedMCS = 1;
15974 if (currentRate > maxRate)
15975 {
15976 maxRate = currentRate;
15977 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015978
Leo Chang6f8870f2013-03-26 18:11:36 -070015979 }
15980 else
15981#endif /* WLAN_FEATURE_11AC */
15982 {
15983 if (rate_flags & eHAL_TX_RATE_HT40)
15984 {
15985 rateFlag |= 1;
15986 }
15987 if (rate_flags & eHAL_TX_RATE_SGI)
15988 {
15989 rateFlag |= 2;
15990 }
15991
Girish Gowli01abcee2014-07-31 20:18:55 +053015992 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053015993 if (rssidx == 1 || rssidx == 2)
15994 {
15995 //get middle rate MCS index if rssi=1/2
15996 for (i=0; i <= 7; i++)
15997 {
15998 if (sinfo->signal <= rssiMcsTbl[mode][i])
15999 {
16000 temp = i+1;
16001 break;
16002 }
16003 }
16004 }
c_hpothu79aab322014-07-14 21:11:01 +053016005
16006 for (i = 0; i < MCSLeng; i++)
16007 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016008 for (j = 0; j < temp; j++)
16009 {
16010 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
16011 {
16012 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016013 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016014 break;
16015 }
16016 }
16017 if ((j < temp) && (currentRate > maxRate))
16018 {
16019 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070016020 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016021 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016022 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016023 }
16024 }
16025
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016026 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
16027 {
16028 maxRate = myRate;
16029 maxSpeedMCS = 1;
16030 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16031 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016032 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053016033 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070016034 {
16035 maxRate = myRate;
16036 if (rate_flags & eHAL_TX_RATE_LEGACY)
16037 {
16038 maxSpeedMCS = 0;
16039 }
16040 else
16041 {
16042 maxSpeedMCS = 1;
16043 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16044 }
16045 }
16046
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016047 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070016048 {
16049 sinfo->txrate.legacy = maxRate;
16050#ifdef LINKSPEED_DEBUG_ENABLED
16051 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
16052#endif //LINKSPEED_DEBUG_ENABLED
16053 }
16054 else
16055 {
16056 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070016057#ifdef WLAN_FEATURE_11AC
16058 sinfo->txrate.nss = 1;
16059 if (rate_flags & eHAL_TX_RATE_VHT80)
16060 {
16061 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016062 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070016063 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016064 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070016065 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016066 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16067 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16068 }
16069 else if (rate_flags & eHAL_TX_RATE_VHT20)
16070 {
16071 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16072 }
16073#endif /* WLAN_FEATURE_11AC */
16074 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
16075 {
16076 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16077 if (rate_flags & eHAL_TX_RATE_HT40)
16078 {
16079 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16080 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016081 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016082 if (rate_flags & eHAL_TX_RATE_SGI)
16083 {
16084 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16085 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016086
Jeff Johnson295189b2012-06-20 16:38:30 -070016087#ifdef LINKSPEED_DEBUG_ENABLED
16088 pr_info("Reporting MCS rate %d flags %x\n",
16089 sinfo->txrate.mcs,
16090 sinfo->txrate.flags );
16091#endif //LINKSPEED_DEBUG_ENABLED
16092 }
16093 }
16094 else
16095 {
16096 // report current rate instead of max rate
16097
16098 if (rate_flags & eHAL_TX_RATE_LEGACY)
16099 {
16100 //provide to the UI in units of 100kbps
16101 sinfo->txrate.legacy = myRate;
16102#ifdef LINKSPEED_DEBUG_ENABLED
16103 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
16104#endif //LINKSPEED_DEBUG_ENABLED
16105 }
16106 else
16107 {
16108 //must be MCS
16109 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016110#ifdef WLAN_FEATURE_11AC
16111 sinfo->txrate.nss = 1;
16112 if (rate_flags & eHAL_TX_RATE_VHT80)
16113 {
16114 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16115 }
16116 else
16117#endif /* WLAN_FEATURE_11AC */
16118 {
16119 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16120 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016121 if (rate_flags & eHAL_TX_RATE_SGI)
16122 {
16123 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16124 }
16125 if (rate_flags & eHAL_TX_RATE_HT40)
16126 {
16127 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16128 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016129#ifdef WLAN_FEATURE_11AC
16130 else if (rate_flags & eHAL_TX_RATE_VHT80)
16131 {
16132 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
16133 }
16134#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070016135#ifdef LINKSPEED_DEBUG_ENABLED
16136 pr_info("Reporting actual MCS rate %d flags %x\n",
16137 sinfo->txrate.mcs,
16138 sinfo->txrate.flags );
16139#endif //LINKSPEED_DEBUG_ENABLED
16140 }
16141 }
16142 sinfo->filled |= STATION_INFO_TX_BITRATE;
16143
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016144 sinfo->tx_packets =
16145 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
16146 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
16147 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
16148 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
16149
16150 sinfo->tx_retries =
16151 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
16152 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
16153 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
16154 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
16155
16156 sinfo->tx_failed =
16157 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
16158 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
16159 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
16160 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
16161
16162 sinfo->filled |=
16163 STATION_INFO_TX_PACKETS |
16164 STATION_INFO_TX_RETRIES |
16165 STATION_INFO_TX_FAILED;
16166
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053016167 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
16168 sinfo->filled |= STATION_INFO_RX_PACKETS;
16169
16170 if (rate_flags & eHAL_TX_RATE_LEGACY)
16171 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
16172 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
16173 sinfo->rx_packets);
16174 else
16175 hddLog(LOG1,
16176 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
16177 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
16178 sinfo->tx_packets, sinfo->rx_packets);
16179
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016180 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16181 TRACE_CODE_HDD_CFG80211_GET_STA,
16182 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016183 EXIT();
16184 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016185}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016186#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16187static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16188 const u8* mac, struct station_info *sinfo)
16189#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016190static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16191 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016192#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016193{
16194 int ret;
16195
16196 vos_ssr_protect(__func__);
16197 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
16198 vos_ssr_unprotect(__func__);
16199
16200 return ret;
16201}
16202
16203static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070016204 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070016205{
16206 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016207 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016208 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016209 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016210
Jeff Johnsone7245742012-09-05 17:12:55 -070016211 ENTER();
16212
Jeff Johnson295189b2012-06-20 16:38:30 -070016213 if (NULL == pAdapter)
16214 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016215 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016216 return -ENODEV;
16217 }
16218
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016219 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16220 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
16221 pAdapter->sessionId, timeout));
16222
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016223 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016224 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016225 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016226 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016227 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016228 }
16229
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016230 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
16231 (TRUE == pHddCtx->hdd_wlan_suspended) &&
16232 (pHddCtx->cfg_ini->fhostArpOffload) &&
16233 (eConnectionState_Associated ==
16234 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
16235 {
Amar Singhald53568e2013-09-26 11:03:45 -070016236
16237 hddLog(VOS_TRACE_LEVEL_INFO,
16238 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053016239 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016240 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16241 {
16242 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016243 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016244 __func__, vos_status);
16245 }
16246 }
16247
Jeff Johnson295189b2012-06-20 16:38:30 -070016248 /**The get power cmd from the supplicant gets updated by the nl only
16249 *on successful execution of the function call
16250 *we are oppositely mapped w.r.t mode in the driver
16251 **/
16252 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
16253
16254 if (VOS_STATUS_E_FAILURE == vos_status)
16255 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16257 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016258 return -EINVAL;
16259 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016260 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016261 return 0;
16262}
16263
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016264static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
16265 struct net_device *dev, bool mode, int timeout)
16266{
16267 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016268
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016269 vos_ssr_protect(__func__);
16270 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
16271 vos_ssr_unprotect(__func__);
16272
16273 return ret;
16274}
Sushant Kaushik084f6592015-09-10 13:11:56 +053016275
Jeff Johnson295189b2012-06-20 16:38:30 -070016276#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016277static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
16278 struct net_device *netdev,
16279 u8 key_index)
16280{
16281 ENTER();
16282 return 0;
16283}
16284
Jeff Johnson295189b2012-06-20 16:38:30 -070016285static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016286 struct net_device *netdev,
16287 u8 key_index)
16288{
16289 int ret;
16290 vos_ssr_protect(__func__);
16291 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
16292 vos_ssr_unprotect(__func__);
16293 return ret;
16294}
16295#endif //LINUX_VERSION_CODE
16296
16297#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16298static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16299 struct net_device *dev,
16300 struct ieee80211_txq_params *params)
16301{
16302 ENTER();
16303 return 0;
16304}
16305#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16306static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16307 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016308{
Jeff Johnsone7245742012-09-05 17:12:55 -070016309 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070016310 return 0;
16311}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016312#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070016313
16314#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16315static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016316 struct net_device *dev,
16317 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016318{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016319 int ret;
16320
16321 vos_ssr_protect(__func__);
16322 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
16323 vos_ssr_unprotect(__func__);
16324 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016325}
16326#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16327static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
16328 struct ieee80211_txq_params *params)
16329{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016330 int ret;
16331
16332 vos_ssr_protect(__func__);
16333 ret = __wlan_hdd_set_txq_params(wiphy, params);
16334 vos_ssr_unprotect(__func__);
16335 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016336}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016337#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016338
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016339static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016340 struct net_device *dev,
16341 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070016342{
16343 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016344 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016345 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016346 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016347 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016348 v_CONTEXT_t pVosContext = NULL;
16349 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016350
Jeff Johnsone7245742012-09-05 17:12:55 -070016351 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016352
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016353 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016354 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016355 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016356 return -EINVAL;
16357 }
16358
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016359 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16360 TRACE_CODE_HDD_CFG80211_DEL_STA,
16361 pAdapter->sessionId, pAdapter->device_mode));
16362
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016363 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16364 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016365 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016366 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016367 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016368 }
16369
Jeff Johnson295189b2012-06-20 16:38:30 -070016370 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016371 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016372 )
16373 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016374 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16375 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16376 if(pSapCtx == NULL){
16377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16378 FL("psapCtx is NULL"));
16379 return -ENOENT;
16380 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016381 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016382 {
16383 v_U16_t i;
16384 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16385 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016386 if ((pSapCtx->aStaInfo[i].isUsed) &&
16387 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016388 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016389 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016390 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016391 ETHER_ADDR_LEN);
16392
Jeff Johnson295189b2012-06-20 16:38:30 -070016393 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016394 "%s: Delete STA with MAC::"
16395 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016396 __func__,
16397 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16398 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016399 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016400 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016401 }
16402 }
16403 }
16404 else
16405 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016406
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016407 vos_status = hdd_softap_GetStaId(pAdapter,
16408 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016409 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16410 {
16411 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016412 "%s: Skip this DEL STA as this is not used::"
16413 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016414 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016415 return -ENOENT;
16416 }
16417
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016418 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016419 {
16420 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016421 "%s: Skip this DEL STA as deauth is in progress::"
16422 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016423 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016424 return -ENOENT;
16425 }
16426
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016427 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016428
Jeff Johnson295189b2012-06-20 16:38:30 -070016429 hddLog(VOS_TRACE_LEVEL_INFO,
16430 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016431 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016432 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016433 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016434
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016435 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016436 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16437 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016438 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016439 hddLog(VOS_TRACE_LEVEL_INFO,
16440 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016441 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016442 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016443 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016444 return -ENOENT;
16445 }
16446
Jeff Johnson295189b2012-06-20 16:38:30 -070016447 }
16448 }
16449
16450 EXIT();
16451
16452 return 0;
16453}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016454
16455#ifdef CFG80211_DEL_STA_V2
16456static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16457 struct net_device *dev,
16458 struct station_del_parameters *param)
16459#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016460#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16461static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16462 struct net_device *dev, const u8 *mac)
16463#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016464static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16465 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016466#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016467#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016468{
16469 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016470 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016471
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016472 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016473
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016474#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016475 if (NULL == param) {
16476 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016477 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016478 return -EINVAL;
16479 }
16480
16481 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16482 param->subtype, &delStaParams);
16483
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016484#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016485 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016486 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016487#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016488 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16489
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016490 vos_ssr_unprotect(__func__);
16491
16492 return ret;
16493}
16494
16495static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016496 struct net_device *dev,
16497#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16498 const u8 *mac,
16499#else
16500 u8 *mac,
16501#endif
16502 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016503{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016504 hdd_adapter_t *pAdapter;
16505 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016506 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016507#ifdef FEATURE_WLAN_TDLS
16508 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016509
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016510 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016511
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016512 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16513 if (NULL == pAdapter)
16514 {
16515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16516 "%s: Adapter is NULL",__func__);
16517 return -EINVAL;
16518 }
16519 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16520 status = wlan_hdd_validate_context(pHddCtx);
16521 if (0 != status)
16522 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016523 return status;
16524 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016525
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016526 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16527 TRACE_CODE_HDD_CFG80211_ADD_STA,
16528 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016529 mask = params->sta_flags_mask;
16530
16531 set = params->sta_flags_set;
16532
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016534 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16535 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016536
16537 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16538 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016539 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016540 }
16541 }
16542#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016543 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016544 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016545}
16546
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016547#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16548static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16549 struct net_device *dev, const u8 *mac,
16550 struct station_parameters *params)
16551#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016552static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16553 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016554#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016555{
16556 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016557
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016558 vos_ssr_protect(__func__);
16559 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16560 vos_ssr_unprotect(__func__);
16561
16562 return ret;
16563}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016564#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016565
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016566static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016567 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016568{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016569 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16570 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016571 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016572 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016573 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016574 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016575
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016576 ENTER();
16577
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016578 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016579 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016580 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016581 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016582 return -EINVAL;
16583 }
16584
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016585 if (!pmksa) {
16586 hddLog(LOGE, FL("pmksa is NULL"));
16587 return -EINVAL;
16588 }
16589
16590 if (!pmksa->bssid || !pmksa->pmkid) {
16591 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16592 pmksa->bssid, pmksa->pmkid);
16593 return -EINVAL;
16594 }
16595
16596 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16597 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16598
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016599 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16600 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016601 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016602 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016603 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016604 }
16605
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016606 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016607 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16608
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016609 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16610 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016611
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016612 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016613 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016614 &pmk_id, 1, FALSE);
16615
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016616 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16617 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16618 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016619
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016620 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016621 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016622}
16623
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016624static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16625 struct cfg80211_pmksa *pmksa)
16626{
16627 int ret;
16628
16629 vos_ssr_protect(__func__);
16630 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16631 vos_ssr_unprotect(__func__);
16632
16633 return ret;
16634}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016635
Wilson Yang6507c4e2013-10-01 20:11:19 -070016636
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016637static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016638 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016639{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016640 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16641 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016642 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016643 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016644
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016645 ENTER();
16646
Wilson Yang6507c4e2013-10-01 20:11:19 -070016647 /* Validate pAdapter */
16648 if (NULL == pAdapter)
16649 {
16650 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16651 return -EINVAL;
16652 }
16653
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016654 if (!pmksa) {
16655 hddLog(LOGE, FL("pmksa is NULL"));
16656 return -EINVAL;
16657 }
16658
16659 if (!pmksa->bssid) {
16660 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16661 return -EINVAL;
16662 }
16663
Kiet Lam98c46a12014-10-31 15:34:57 -070016664 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16665 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16666
Wilson Yang6507c4e2013-10-01 20:11:19 -070016667 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16668 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016669 if (0 != status)
16670 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016671 return status;
16672 }
16673
16674 /*Retrieve halHandle*/
16675 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16676
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016677 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16678 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16679 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016680 /* Delete the PMKID CSR cache */
16681 if (eHAL_STATUS_SUCCESS !=
16682 sme_RoamDelPMKIDfromCache(halHandle,
16683 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16684 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16685 MAC_ADDR_ARRAY(pmksa->bssid));
16686 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016687 }
16688
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016689 EXIT();
16690 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016691}
16692
Wilson Yang6507c4e2013-10-01 20:11:19 -070016693
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016694static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16695 struct cfg80211_pmksa *pmksa)
16696{
16697 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016698
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016699 vos_ssr_protect(__func__);
16700 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16701 vos_ssr_unprotect(__func__);
16702
16703 return ret;
16704
16705}
16706
16707static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016708{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016709 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16710 tHalHandle halHandle;
16711 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016712 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016713
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016714 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016715
16716 /* Validate pAdapter */
16717 if (NULL == pAdapter)
16718 {
16719 hddLog(VOS_TRACE_LEVEL_ERROR,
16720 "%s: Invalid Adapter" ,__func__);
16721 return -EINVAL;
16722 }
16723
16724 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16725 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016726 if (0 != status)
16727 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016728 return status;
16729 }
16730
16731 /*Retrieve halHandle*/
16732 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16733
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016734 /* Flush the PMKID cache in CSR */
16735 if (eHAL_STATUS_SUCCESS !=
16736 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
16737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
16738 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016739 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016740 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080016741 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016742}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016743
16744static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
16745{
16746 int ret;
16747
16748 vos_ssr_protect(__func__);
16749 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
16750 vos_ssr_unprotect(__func__);
16751
16752 return ret;
16753}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016754#endif
16755
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016756#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016757static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16758 struct net_device *dev,
16759 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016760{
16761 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16762 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016763 hdd_context_t *pHddCtx;
16764 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016765
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016766 ENTER();
16767
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016768 if (NULL == pAdapter)
16769 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016770 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016771 return -ENODEV;
16772 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016773 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16774 ret = wlan_hdd_validate_context(pHddCtx);
16775 if (0 != ret)
16776 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016777 return ret;
16778 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016779 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016780 if (NULL == pHddStaCtx)
16781 {
16782 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
16783 return -EINVAL;
16784 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016785
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016786 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16787 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
16788 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016789 // Added for debug on reception of Re-assoc Req.
16790 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
16791 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016792 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016793 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080016794 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016795 }
16796
16797#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080016798 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016799 ftie->ie_len);
16800#endif
16801
16802 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016803 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
16804 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016805 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016806
16807 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016808 return 0;
16809}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016810
16811static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16812 struct net_device *dev,
16813 struct cfg80211_update_ft_ies_params *ftie)
16814{
16815 int ret;
16816
16817 vos_ssr_protect(__func__);
16818 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
16819 vos_ssr_unprotect(__func__);
16820
16821 return ret;
16822}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016823#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016824
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016825#ifdef FEATURE_WLAN_SCAN_PNO
16826
16827void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
16828 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
16829{
16830 int ret;
16831 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
16832 hdd_context_t *pHddCtx;
16833
Nirav Shah80830bf2013-12-31 16:35:12 +053016834 ENTER();
16835
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016836 if (NULL == pAdapter)
16837 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016839 "%s: HDD adapter is Null", __func__);
16840 return ;
16841 }
16842
16843 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16844 if (NULL == pHddCtx)
16845 {
16846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16847 "%s: HDD context is Null!!!", __func__);
16848 return ;
16849 }
16850
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016851 spin_lock(&pHddCtx->schedScan_lock);
16852 if (TRUE == pHddCtx->isWiphySuspended)
16853 {
16854 pHddCtx->isSchedScanUpdatePending = TRUE;
16855 spin_unlock(&pHddCtx->schedScan_lock);
16856 hddLog(VOS_TRACE_LEVEL_INFO,
16857 "%s: Update cfg80211 scan database after it resume", __func__);
16858 return ;
16859 }
16860 spin_unlock(&pHddCtx->schedScan_lock);
16861
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016862 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
16863
16864 if (0 > ret)
16865 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053016866 else
16867 {
16868 /* Acquire wakelock to handle the case where APP's tries to suspend
16869 * immediatly after the driver gets connect request(i.e after pno)
16870 * from supplicant, this result in app's is suspending and not able
16871 * to process the connect request to AP */
16872 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
16873 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016874 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16876 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016877}
16878
16879/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016880 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016881 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016882 */
16883static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
16884{
16885 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16886 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016887 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016888 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16889 int status = 0;
16890 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
16891
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016892 /* The current firmware design does not allow PNO during any
16893 * active sessions. Hence, determine the active sessions
16894 * and return a failure.
16895 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016896 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
16897 {
16898 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016899 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016900
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016901 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
16902 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
16903 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
16904 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
16905 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053016906 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016907 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016908 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016909 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016910 }
16911 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16912 pAdapterNode = pNext;
16913 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016914 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016915}
16916
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016917void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
16918{
16919 hdd_adapter_t *pAdapter = callbackContext;
16920 hdd_context_t *pHddCtx;
16921
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016922 ENTER();
16923
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016924 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
16925 {
16926 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16927 FL("Invalid adapter or adapter has invalid magic"));
16928 return;
16929 }
16930
16931 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16932 if (0 != wlan_hdd_validate_context(pHddCtx))
16933 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016934 return;
16935 }
16936
c_hpothub53c45d2014-08-18 16:53:14 +053016937 if (VOS_STATUS_SUCCESS != status)
16938 {
16939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016940 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053016941 pHddCtx->isPnoEnable = FALSE;
16942 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016943
16944 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
16945 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016946 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016947}
16948
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016949/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016950 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
16951 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016952 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016953static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016954 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16955{
16956 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016957 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016958 hdd_context_t *pHddCtx;
16959 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016960 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053016961 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
16962 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016963 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16964 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016965 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016966 hdd_config_t *pConfig = NULL;
16967 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016968
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016969 ENTER();
16970
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016971 if (NULL == pAdapter)
16972 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016974 "%s: HDD adapter is Null", __func__);
16975 return -ENODEV;
16976 }
16977
16978 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016979 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016980
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016981 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016982 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016983 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016984 }
16985
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016986 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016987 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16988 if (NULL == hHal)
16989 {
16990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16991 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016992 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016993 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016994 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16995 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
16996 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053016997 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016998 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053016999 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017000 {
17001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17002 "%s: aborting the existing scan is unsuccessfull", __func__);
17003 return -EBUSY;
17004 }
17005
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017006 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017007 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017008 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017009 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017010 return -EBUSY;
17011 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017012
c_hpothu37f21312014-04-09 21:49:54 +053017013 if (TRUE == pHddCtx->isPnoEnable)
17014 {
17015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17016 FL("already PNO is enabled"));
17017 return -EBUSY;
17018 }
c_hpothu225aa7c2014-10-22 17:45:13 +053017019
17020 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
17021 {
17022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17023 "%s: abort ROC failed ", __func__);
17024 return -EBUSY;
17025 }
17026
c_hpothu37f21312014-04-09 21:49:54 +053017027 pHddCtx->isPnoEnable = TRUE;
17028
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017029 pnoRequest.enable = 1; /*Enable PNO */
17030 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017031
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017032 if (( !pnoRequest.ucNetworksCount ) ||
17033 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017034 {
17035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017036 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017037 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017038 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017039 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017040 goto error;
17041 }
17042
17043 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
17044 {
17045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017046 "%s: Incorrect number of channels %d",
17047 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017048 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017049 goto error;
17050 }
17051
17052 /* Framework provides one set of channels(all)
17053 * common for all saved profile */
17054 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17055 channels_allowed, &num_channels_allowed))
17056 {
17057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17058 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017059 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017060 goto error;
17061 }
17062 /* Checking each channel against allowed channel list */
17063 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053017064 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017065 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017066 char chList [(request->n_channels*5)+1];
17067 int len;
17068 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017069 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017070 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017071 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017072 if (request->channels[i]->hw_value == channels_allowed[indx])
17073 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017074 if ((!pConfig->enableDFSPnoChnlScan) &&
17075 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
17076 {
17077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17078 "%s : Dropping DFS channel : %d",
17079 __func__,channels_allowed[indx]);
17080 num_ignore_dfs_ch++;
17081 break;
17082 }
17083
Nirav Shah80830bf2013-12-31 16:35:12 +053017084 valid_ch[num_ch++] = request->channels[i]->hw_value;
17085 len += snprintf(chList+len, 5, "%d ",
17086 request->channels[i]->hw_value);
17087 break ;
17088 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017089 }
17090 }
Nirav Shah80830bf2013-12-31 16:35:12 +053017091 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017092
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017093 /*If all channels are DFS and dropped, then ignore the PNO request*/
17094 if (num_ignore_dfs_ch == request->n_channels)
17095 {
17096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17097 "%s : All requested channels are DFS channels", __func__);
17098 ret = -EINVAL;
17099 goto error;
17100 }
17101 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017102
17103 pnoRequest.aNetworks =
17104 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17105 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017106 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017107 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17108 FL("failed to allocate memory aNetworks %u"),
17109 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17110 goto error;
17111 }
17112 vos_mem_zero(pnoRequest.aNetworks,
17113 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17114
17115 /* Filling per profile params */
17116 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
17117 {
17118 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017119 request->match_sets[i].ssid.ssid_len;
17120
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017121 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
17122 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017123 {
17124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017125 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017126 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017127 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017128 goto error;
17129 }
17130
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017131 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017132 request->match_sets[i].ssid.ssid,
17133 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17135 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017136 i, pnoRequest.aNetworks[i].ssId.ssId);
17137 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
17138 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
17139 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017140
17141 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017142 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
17143 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017144
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017145 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017146 }
17147
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017148 for (i = 0; i < request->n_ssids; i++)
17149 {
17150 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017151 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017152 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017153 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017154 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017155 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017156 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017157 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017158 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017159 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017160 break;
17161 }
17162 j++;
17163 }
17164 }
17165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17166 "Number of hidden networks being Configured = %d",
17167 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080017169 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017170
17171 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17172 if (pnoRequest.p24GProbeTemplate == NULL)
17173 {
17174 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17175 FL("failed to allocate memory p24GProbeTemplate %u"),
17176 SIR_PNO_MAX_PB_REQ_SIZE);
17177 goto error;
17178 }
17179
17180 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17181 if (pnoRequest.p5GProbeTemplate == NULL)
17182 {
17183 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17184 FL("failed to allocate memory p5GProbeTemplate %u"),
17185 SIR_PNO_MAX_PB_REQ_SIZE);
17186 goto error;
17187 }
17188
17189 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17190 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17191
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053017192 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
17193 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017194 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017195 pnoRequest.us24GProbeTemplateLen = request->ie_len;
17196 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
17197 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017198
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017199 pnoRequest.us5GProbeTemplateLen = request->ie_len;
17200 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
17201 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017202 }
17203
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017204 /* Driver gets only one time interval which is hardcoded in
17205 * supplicant for 10000ms. Taking power consumption into account 6 timers
17206 * will be used, Timervalue is increased exponentially i.e 10,20,40,
17207 * 80,160,320 secs. And number of scan cycle for each timer
17208 * is configurable through INI param gPNOScanTimerRepeatValue.
17209 * If it is set to 0 only one timer will be used and PNO scan cycle
17210 * will be repeated after each interval specified by supplicant
17211 * till PNO is disabled.
17212 */
17213 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017214 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017215 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017216 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017217 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
17218
17219 tempInterval = (request->interval)/1000;
17220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17221 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
17222 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017223 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017224 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017225 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017226 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017227 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017228 tempInterval *= 2;
17229 }
17230 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017231 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017232
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017233 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017234
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017235 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017236 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17237 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017238 pAdapter->pno_req_status = 0;
17239
Nirav Shah80830bf2013-12-31 16:35:12 +053017240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17241 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017242 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
17243 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053017244
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017245 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017246 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017247 hdd_cfg80211_sched_scan_done_callback, pAdapter);
17248 if (eHAL_STATUS_SUCCESS != status)
17249 {
17250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017251 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017252 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017253 goto error;
17254 }
17255
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017256 ret = wait_for_completion_timeout(
17257 &pAdapter->pno_comp_var,
17258 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17259 if (0 >= ret)
17260 {
17261 // Did not receive the response for PNO enable in time.
17262 // Assuming the PNO enable was success.
17263 // Returning error from here, because we timeout, results
17264 // in side effect of Wifi (Wifi Setting) not to work.
17265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17266 FL("Timed out waiting for PNO to be Enabled"));
17267 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017268 }
17269
17270 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053017271 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017272
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017273error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17275 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053017276 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017277 if (pnoRequest.aNetworks)
17278 vos_mem_free(pnoRequest.aNetworks);
17279 if (pnoRequest.p24GProbeTemplate)
17280 vos_mem_free(pnoRequest.p24GProbeTemplate);
17281 if (pnoRequest.p5GProbeTemplate)
17282 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017283
17284 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017285 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017286}
17287
17288/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017289 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
17290 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017291 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017292static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
17293 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17294{
17295 int ret;
17296
17297 vos_ssr_protect(__func__);
17298 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
17299 vos_ssr_unprotect(__func__);
17300
17301 return ret;
17302}
17303
17304/*
17305 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
17306 * Function to disable PNO
17307 */
17308static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017309 struct net_device *dev)
17310{
17311 eHalStatus status = eHAL_STATUS_FAILURE;
17312 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17313 hdd_context_t *pHddCtx;
17314 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017315 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017316 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017317
17318 ENTER();
17319
17320 if (NULL == pAdapter)
17321 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017323 "%s: HDD adapter is Null", __func__);
17324 return -ENODEV;
17325 }
17326
17327 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017328
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017329 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017330 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017331 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017332 "%s: HDD context is Null", __func__);
17333 return -ENODEV;
17334 }
17335
17336 /* The return 0 is intentional when isLogpInProgress and
17337 * isLoadUnloadInProgress. We did observe a crash due to a return of
17338 * failure in sched_scan_stop , especially for a case where the unload
17339 * of the happens at the same time. The function __cfg80211_stop_sched_scan
17340 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
17341 * success. If it returns a failure , then its next invocation due to the
17342 * clean up of the second interface will have the dev pointer corresponding
17343 * to the first one leading to a crash.
17344 */
17345 if (pHddCtx->isLogpInProgress)
17346 {
17347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17348 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017349 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017350 return ret;
17351 }
17352
Mihir Shete18156292014-03-11 15:38:30 +053017353 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017354 {
17355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17356 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17357 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017358 }
17359
17360 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17361 if (NULL == hHal)
17362 {
17363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17364 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017365 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017366 }
17367
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017368 pnoRequest.enable = 0; /* Disable PNO */
17369 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017370
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017371 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17372 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17373 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017374
17375 INIT_COMPLETION(pAdapter->pno_comp_var);
17376 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17377 pnoRequest.callbackContext = pAdapter;
17378 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017379 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017380 pAdapter->sessionId,
17381 NULL, pAdapter);
17382 if (eHAL_STATUS_SUCCESS != status)
17383 {
17384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17385 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017386 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017387 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017388 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017389 ret = wait_for_completion_timeout(
17390 &pAdapter->pno_comp_var,
17391 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17392 if (0 >= ret)
17393 {
17394 // Did not receive the response for PNO disable in time.
17395 // Assuming the PNO disable was success.
17396 // Returning error from here, because we timeout, results
17397 // in side effect of Wifi (Wifi Setting) not to work.
17398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17399 FL("Timed out waiting for PNO to be disabled"));
17400 ret = 0;
17401 }
17402
17403 ret = pAdapter->pno_req_status;
17404 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017405
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017406error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017408 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017409
17410 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017411 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017412}
17413
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017414/*
17415 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17416 * NL interface to disable PNO
17417 */
17418static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17419 struct net_device *dev)
17420{
17421 int ret;
17422
17423 vos_ssr_protect(__func__);
17424 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17425 vos_ssr_unprotect(__func__);
17426
17427 return ret;
17428}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017429#endif /*FEATURE_WLAN_SCAN_PNO*/
17430
17431
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017432#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017433#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017434static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17435 struct net_device *dev,
17436 u8 *peer, u8 action_code,
17437 u8 dialog_token,
17438 u16 status_code, u32 peer_capability,
17439 const u8 *buf, size_t len)
17440#else /* TDLS_MGMT_VERSION2 */
17441#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17442static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17443 struct net_device *dev,
17444 const u8 *peer, u8 action_code,
17445 u8 dialog_token, u16 status_code,
17446 u32 peer_capability, bool initiator,
17447 const u8 *buf, size_t len)
17448#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17449static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17450 struct net_device *dev,
17451 const u8 *peer, u8 action_code,
17452 u8 dialog_token, u16 status_code,
17453 u32 peer_capability, const u8 *buf,
17454 size_t len)
17455#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17456static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17457 struct net_device *dev,
17458 u8 *peer, u8 action_code,
17459 u8 dialog_token,
17460 u16 status_code, u32 peer_capability,
17461 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017462#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017463static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17464 struct net_device *dev,
17465 u8 *peer, u8 action_code,
17466 u8 dialog_token,
17467 u16 status_code, const u8 *buf,
17468 size_t len)
17469#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017470#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017471{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017472 hdd_adapter_t *pAdapter;
17473 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017474 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017475 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017476 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017477 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017478 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017479 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017480#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017481 u32 peer_capability = 0;
17482#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017483 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017484 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017485
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017486 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17487 if (NULL == pAdapter)
17488 {
17489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17490 "%s: Adapter is NULL",__func__);
17491 return -EINVAL;
17492 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017493 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17494 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17495 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017496
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017497 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017498 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017499 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017501 "Invalid arguments");
17502 return -EINVAL;
17503 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017504
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017505 if (pHddCtx->isLogpInProgress)
17506 {
17507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17508 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017509 wlan_hdd_tdls_set_link_status(pAdapter,
17510 peer,
17511 eTDLS_LINK_IDLE,
17512 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017513 return -EBUSY;
17514 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017515
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017516 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17517 {
17518 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17519 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17520 return -EAGAIN;
17521 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017522
Hoonki Lee27511902013-03-14 18:19:06 -070017523 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017524 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017526 "%s: TDLS mode is disabled OR not enabled in FW."
17527 MAC_ADDRESS_STR " action %d declined.",
17528 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017529 return -ENOTSUPP;
17530 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017531
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017532 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17533
17534 if( NULL == pHddStaCtx )
17535 {
17536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17537 "%s: HDD station context NULL ",__func__);
17538 return -EINVAL;
17539 }
17540
17541 /* STA should be connected and authenticated
17542 * before sending any TDLS frames
17543 */
17544 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17545 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17546 {
17547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17548 "STA is not connected or unauthenticated. "
17549 "connState %u, uIsAuthenticated %u",
17550 pHddStaCtx->conn_info.connState,
17551 pHddStaCtx->conn_info.uIsAuthenticated);
17552 return -EAGAIN;
17553 }
17554
Hoonki Lee27511902013-03-14 18:19:06 -070017555 /* other than teardown frame, other mgmt frames are not sent if disabled */
17556 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17557 {
17558 /* if tdls_mode is disabled to respond to peer's request */
17559 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17560 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017562 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017563 " TDLS mode is disabled. action %d declined.",
17564 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017565
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017566 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017567 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017568
17569 if (vos_max_concurrent_connections_reached())
17570 {
17571 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17572 return -EINVAL;
17573 }
Hoonki Lee27511902013-03-14 18:19:06 -070017574 }
17575
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017576 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17577 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017578 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017579 {
17580 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017581 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017582 " TDLS setup is ongoing. action %d declined.",
17583 __func__, MAC_ADDR_ARRAY(peer), action_code);
17584 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017585 }
17586 }
17587
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017588 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17589 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017590 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017591 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17592 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017593 {
17594 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17595 we return error code at 'add_station()'. Hence we have this
17596 check again in addtion to add_station().
17597 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017598 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017599 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17601 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017602 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
17603 __func__, MAC_ADDR_ARRAY(peer), action_code,
17604 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053017605 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080017606 }
17607 else
17608 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017609 /* maximum reached. tweak to send error code to peer and return
17610 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017611 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17613 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017614 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
17615 __func__, MAC_ADDR_ARRAY(peer), status_code,
17616 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070017617 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017618 /* fall through to send setup resp with failure status
17619 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017620 }
17621 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017622 else
17623 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017624 mutex_lock(&pHddCtx->tdls_lock);
17625 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017626 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017627 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017628 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017629 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017630 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17631 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017632 return -EPERM;
17633 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017634 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017635 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017636 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017637
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017639 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017640 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17641 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017642
Hoonki Leea34dd892013-02-05 22:56:02 -080017643 /*Except teardown responder will not be used so just make 0*/
17644 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017645 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017646 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017647
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017648 mutex_lock(&pHddCtx->tdls_lock);
17649 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017650
17651 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17652 responder = pTdlsPeer->is_responder;
17653 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017654 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017656 "%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 -070017657 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17658 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017659 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017660 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017661 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017662 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017663 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017664
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017665 /* Discard TDLS setup if peer is removed by user app */
17666 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
17667 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17668 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
17669 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
17670
17671 mutex_lock(&pHddCtx->tdls_lock);
17672 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17673 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
17674 mutex_unlock(&pHddCtx->tdls_lock);
17675 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
17676 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
17677 MAC_ADDR_ARRAY(peer), action_code);
17678 return -EINVAL;
17679 }
17680 mutex_unlock(&pHddCtx->tdls_lock);
17681 }
17682
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017683 /* For explicit trigger of DIS_REQ come out of BMPS for
17684 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017685 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053017686 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017687 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17688 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070017689 {
17690 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
17691 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017692 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017693 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017694 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
17695 if (status != VOS_STATUS_SUCCESS) {
17696 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
17697 }
Hoonki Lee14621352013-04-16 17:51:19 -070017698 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017699 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017700 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017701 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
17702 }
17703 }
Hoonki Lee14621352013-04-16 17:51:19 -070017704 }
17705
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017706 /* make sure doesn't call send_mgmt() while it is pending */
17707 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
17708 {
17709 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017710 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017711 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017712 ret = -EBUSY;
17713 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017714 }
17715
17716 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017717 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
17718
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017719 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
17720 pAdapter->sessionId, peer, action_code, dialog_token,
17721 status_code, peer_capability, (tANI_U8 *)buf, len,
17722 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017723
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017724 if (VOS_STATUS_SUCCESS != status)
17725 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17727 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017728 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017729 ret = -EINVAL;
17730 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017731 }
17732
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17734 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
17735 WAIT_TIME_TDLS_MGMT);
17736
Hoonki Leed37cbb32013-04-20 00:31:14 -070017737 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
17738 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
17739
17740 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017741 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070017742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070017743 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070017744 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017745 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080017746
17747 if (pHddCtx->isLogpInProgress)
17748 {
17749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17750 "%s: LOGP in Progress. Ignore!!!", __func__);
17751 return -EAGAIN;
17752 }
Abhishek Singh837adf22015-10-01 17:37:37 +053017753 if (rc <= 0)
17754 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
17755 WLAN_LOG_INDICATOR_HOST_DRIVER,
17756 WLAN_LOG_REASON_HDD_TIME_OUT,
17757 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080017758
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017759 ret = -EINVAL;
17760 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017761 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017762 else
17763 {
17764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17765 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
17766 __func__, rc, pAdapter->mgmtTxCompletionStatus);
17767 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017768
Gopichand Nakkala05922802013-03-14 12:23:19 -070017769 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070017770 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017771 ret = max_sta_failed;
17772 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070017773 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017774
Hoonki Leea34dd892013-02-05 22:56:02 -080017775 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
17776 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017777 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17779 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017780 }
17781 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
17782 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017783 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17785 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017786 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017787
17788 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017789
17790tx_failed:
17791 /* add_station will be called before sending TDLS_SETUP_REQ and
17792 * TDLS_SETUP_RSP and as part of add_station driver will enable
17793 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
17794 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
17795 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
17796 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
17797 */
17798
17799 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17800 (SIR_MAC_TDLS_SETUP_RSP == action_code))
17801 wlan_hdd_tdls_check_bmps(pAdapter);
17802 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017803}
17804
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017805#if TDLS_MGMT_VERSION2
17806static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17807 u8 *peer, u8 action_code, u8 dialog_token,
17808 u16 status_code, u32 peer_capability,
17809 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017810#else /* TDLS_MGMT_VERSION2 */
17811#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17812static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17813 struct net_device *dev,
17814 const u8 *peer, u8 action_code,
17815 u8 dialog_token, u16 status_code,
17816 u32 peer_capability, bool initiator,
17817 const u8 *buf, size_t len)
17818#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17819static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17820 struct net_device *dev,
17821 const u8 *peer, u8 action_code,
17822 u8 dialog_token, u16 status_code,
17823 u32 peer_capability, const u8 *buf,
17824 size_t len)
17825#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17826static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17827 struct net_device *dev,
17828 u8 *peer, u8 action_code,
17829 u8 dialog_token,
17830 u16 status_code, u32 peer_capability,
17831 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017832#else
17833static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17834 u8 *peer, u8 action_code, u8 dialog_token,
17835 u16 status_code, const u8 *buf, size_t len)
17836#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017837#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017838{
17839 int ret;
17840
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017841 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017842#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017843 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17844 dialog_token, status_code,
17845 peer_capability, buf, len);
17846#else /* TDLS_MGMT_VERSION2 */
17847#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17848 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17849 dialog_token, status_code,
17850 peer_capability, initiator,
17851 buf, len);
17852#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17853 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17854 dialog_token, status_code,
17855 peer_capability, buf, len);
17856#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17857 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17858 dialog_token, status_code,
17859 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017860#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017861 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17862 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017863#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017864#endif
17865 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017866
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017867 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017868}
Atul Mittal115287b2014-07-08 13:26:33 +053017869
17870int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017871#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17872 const u8 *peer,
17873#else
Atul Mittal115287b2014-07-08 13:26:33 +053017874 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017875#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017876 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053017877 cfg80211_exttdls_callback callback)
17878{
17879
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017880 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053017881 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017882 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053017883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17884 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
17885 __func__, MAC_ADDR_ARRAY(peer));
17886
17887 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17888 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17889
17890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017891 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17892 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17893 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017894 return -ENOTSUPP;
17895 }
17896
17897 /* To cater the requirement of establishing the TDLS link
17898 * irrespective of the data traffic , get an entry of TDLS peer.
17899 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017900 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017901 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
17902 if (pTdlsPeer == NULL) {
17903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17904 "%s: peer " MAC_ADDRESS_STR " not existing",
17905 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017906 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017907 return -EINVAL;
17908 }
17909
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017910 /* check FW TDLS Off Channel capability */
17911 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017912 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017913 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017914 {
17915 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
17916 pTdlsPeer->peerParams.global_operating_class =
17917 tdls_peer_params->global_operating_class;
17918 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
17919 pTdlsPeer->peerParams.min_bandwidth_kbps =
17920 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017921 /* check configured channel is valid, non dfs and
17922 * not current operating channel */
17923 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
17924 tdls_peer_params->channel)) &&
17925 (pHddStaCtx) &&
17926 (tdls_peer_params->channel !=
17927 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017928 {
17929 pTdlsPeer->isOffChannelConfigured = TRUE;
17930 }
17931 else
17932 {
17933 pTdlsPeer->isOffChannelConfigured = FALSE;
17934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17935 "%s: Configured Tdls Off Channel is not valid", __func__);
17936
17937 }
17938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017939 "%s: tdls_off_channel %d isOffChannelConfigured %d "
17940 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017941 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017942 pTdlsPeer->isOffChannelConfigured,
17943 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017944 }
17945 else
17946 {
17947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017948 "%s: TDLS off channel FW capability %d, "
17949 "host capab %d or Invalid TDLS Peer Params", __func__,
17950 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
17951 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017952 }
17953
Atul Mittal115287b2014-07-08 13:26:33 +053017954 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
17955
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017956 mutex_unlock(&pHddCtx->tdls_lock);
17957
Atul Mittal115287b2014-07-08 13:26:33 +053017958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17959 " %s TDLS Add Force Peer Failed",
17960 __func__);
17961 return -EINVAL;
17962 }
17963 /*EXT TDLS*/
17964
17965 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017966 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17968 " %s TDLS set callback Failed",
17969 __func__);
17970 return -EINVAL;
17971 }
17972
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017973 mutex_unlock(&pHddCtx->tdls_lock);
17974
Atul Mittal115287b2014-07-08 13:26:33 +053017975 return(0);
17976
17977}
17978
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017979int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
17980#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17981 const u8 *peer
17982#else
17983 u8 *peer
17984#endif
17985)
Atul Mittal115287b2014-07-08 13:26:33 +053017986{
17987
17988 hddTdlsPeer_t *pTdlsPeer;
17989 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053017990
Atul Mittal115287b2014-07-08 13:26:33 +053017991 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17992 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
17993 __func__, MAC_ADDR_ARRAY(peer));
17994
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017995 if (0 != wlan_hdd_validate_context(pHddCtx)) {
17996 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
17997 return -EINVAL;
17998 }
17999
Atul Mittal115287b2014-07-08 13:26:33 +053018000 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18001 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18002
18003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018004 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18005 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18006 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018007 return -ENOTSUPP;
18008 }
18009
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018010 mutex_lock(&pHddCtx->tdls_lock);
18011 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053018012
18013 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018014 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018015 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018016 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053018017 __func__, MAC_ADDR_ARRAY(peer));
18018 return -EINVAL;
18019 }
18020 else {
18021 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
18022 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018023 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
18024 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018025 /* if channel switch is configured, reset
18026 the channel for this peer */
18027 if (TRUE == pTdlsPeer->isOffChannelConfigured)
18028 {
18029 pTdlsPeer->peerParams.channel = 0;
18030 pTdlsPeer->isOffChannelConfigured = FALSE;
18031 }
Atul Mittal115287b2014-07-08 13:26:33 +053018032 }
18033
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018034 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018035 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018036 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053018037 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018038 }
Atul Mittal115287b2014-07-08 13:26:33 +053018039
18040 /*EXT TDLS*/
18041
18042 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018043 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18045 " %s TDLS set callback Failed",
18046 __func__);
18047 return -EINVAL;
18048 }
Atul Mittal115287b2014-07-08 13:26:33 +053018049
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018050 mutex_unlock(&pHddCtx->tdls_lock);
18051
18052 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053018053}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018054static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018055#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18056 const u8 *peer,
18057#else
18058 u8 *peer,
18059#endif
18060 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018061{
18062 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18063 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018064 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018065 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018066
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018067 ENTER();
18068
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018069 if (!pAdapter) {
18070 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
18071 return -EINVAL;
18072 }
18073
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018074 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18075 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
18076 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018077 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018078 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070018080 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018081 return -EINVAL;
18082 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018083
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018084 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018085 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018086 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018087 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018088 }
18089
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018090
18091 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018092 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018093 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018095 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
18096 "Cannot process TDLS commands",
18097 pHddCtx->cfg_ini->fEnableTDLSSupport,
18098 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018099 return -ENOTSUPP;
18100 }
18101
18102 switch (oper) {
18103 case NL80211_TDLS_ENABLE_LINK:
18104 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018105 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018106 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053018107 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
18108 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053018109 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018110 tANI_U16 numCurrTdlsPeers = 0;
18111 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018112 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018113 tSirMacAddr peerMac;
18114 int channel;
18115 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018116
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18118 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
18119 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018120
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018121 mutex_lock(&pHddCtx->tdls_lock);
18122 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018123 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053018124 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018125 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018126 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18127 " (oper %d) not exsting. ignored",
18128 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18129 return -EINVAL;
18130 }
18131
18132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18133 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18134 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18135 "NL80211_TDLS_ENABLE_LINK");
18136
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018137 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
18138 {
18139 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
18140 MAC_ADDRESS_STR " failed",
18141 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018142 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018143 return -EINVAL;
18144 }
18145
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018146 /* before starting tdls connection, set tdls
18147 * off channel established status to default value */
18148 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018149
18150 mutex_unlock(&pHddCtx->tdls_lock);
18151
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053018152 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018153 /* TDLS Off Channel, Disable tdls channel switch,
18154 when there are more than one tdls link */
18155 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053018156 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018157 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018158 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018159 /* get connected peer and send disable tdls off chan */
18160 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018161 if ((connPeer) &&
18162 (connPeer->isOffChannelSupported == TRUE) &&
18163 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018164 {
18165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18166 "%s: More then one peer connected, Disable "
18167 "TDLS channel switch", __func__);
18168
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018169 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018170 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
18171 channel = connPeer->peerParams.channel;
18172
18173 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018174
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018175 ret = sme_SendTdlsChanSwitchReq(
18176 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018177 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018178 peerMac,
18179 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018180 TDLS_OFF_CHANNEL_BW_OFFSET,
18181 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018182 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018183 hddLog(VOS_TRACE_LEVEL_ERROR,
18184 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018185 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018186 }
18187 else
18188 {
18189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18190 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018191 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018192 "isOffChannelConfigured %d",
18193 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018194 (connPeer ? (connPeer->isOffChannelSupported)
18195 : -1),
18196 (connPeer ? (connPeer->isOffChannelConfigured)
18197 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018198 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018199 }
18200 }
18201
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018202 mutex_lock(&pHddCtx->tdls_lock);
18203 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18204 if ( NULL == pTdlsPeer ) {
18205 mutex_unlock(&pHddCtx->tdls_lock);
18206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18207 "%s: " MAC_ADDRESS_STR
18208 " (oper %d) peer got freed in other context. ignored",
18209 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18210 return -EINVAL;
18211 }
18212 peer_status = pTdlsPeer->link_status;
18213 mutex_unlock(&pHddCtx->tdls_lock);
18214
18215 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018216 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018217 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053018218
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018219 if (0 != wlan_hdd_tdls_get_link_establish_params(
18220 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018221 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018222 return -EINVAL;
18223 }
18224 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018225
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018226 ret = sme_SendTdlsLinkEstablishParams(
18227 WLAN_HDD_GET_HAL_CTX(pAdapter),
18228 pAdapter->sessionId, peer,
18229 &tdlsLinkEstablishParams);
18230 if (ret != VOS_STATUS_SUCCESS) {
18231 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
18232 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018233 /* Send TDLS peer UAPSD capabilities to the firmware and
18234 * register with the TL on after the response for this operation
18235 * is received .
18236 */
18237 ret = wait_for_completion_interruptible_timeout(
18238 &pAdapter->tdls_link_establish_req_comp,
18239 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053018240
18241 mutex_lock(&pHddCtx->tdls_lock);
18242 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18243 if ( NULL == pTdlsPeer ) {
18244 mutex_unlock(&pHddCtx->tdls_lock);
18245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18246 "%s %d: " MAC_ADDRESS_STR
18247 " (oper %d) peer got freed in other context. ignored",
18248 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
18249 (int)oper);
18250 return -EINVAL;
18251 }
18252 peer_status = pTdlsPeer->link_status;
18253 mutex_unlock(&pHddCtx->tdls_lock);
18254
18255 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018256 {
18257 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018258 FL("Link Establish Request Failed Status %ld"),
18259 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018260 return -EINVAL;
18261 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018262 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018263
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018264 mutex_lock(&pHddCtx->tdls_lock);
18265 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18266 if ( NULL == pTdlsPeer ) {
18267 mutex_unlock(&pHddCtx->tdls_lock);
18268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18269 "%s: " MAC_ADDRESS_STR
18270 " (oper %d) peer got freed in other context. ignored",
18271 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18272 return -EINVAL;
18273 }
18274
Atul Mittal115287b2014-07-08 13:26:33 +053018275 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18276 eTDLS_LINK_CONNECTED,
18277 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018278 staDesc.ucSTAId = pTdlsPeer->staId;
18279 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053018280
18281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18282 "%s: tdlsLinkEstablishParams of peer "
18283 MAC_ADDRESS_STR "uapsdQueues: %d"
18284 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
18285 "isResponder: %d peerstaId: %d",
18286 __func__,
18287 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
18288 tdlsLinkEstablishParams.uapsdQueues,
18289 tdlsLinkEstablishParams.qos,
18290 tdlsLinkEstablishParams.maxSp,
18291 tdlsLinkEstablishParams.isBufSta,
18292 tdlsLinkEstablishParams.isOffChannelSupported,
18293 tdlsLinkEstablishParams.isResponder,
18294 pTdlsPeer->staId);
18295
18296 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18297 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
18298 __func__,
18299 staDesc.ucSTAId,
18300 staDesc.ucQosEnabled);
18301
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018302 ret = WLANTL_UpdateTdlsSTAClient(
18303 pHddCtx->pvosContext,
18304 &staDesc);
18305 if (ret != VOS_STATUS_SUCCESS) {
18306 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
18307 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053018308
Gopichand Nakkala471708b2013-06-04 20:03:01 +053018309 /* Mark TDLS client Authenticated .*/
18310 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
18311 pTdlsPeer->staId,
18312 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018313 if (VOS_STATUS_SUCCESS == status)
18314 {
Hoonki Lee14621352013-04-16 17:51:19 -070018315 if (pTdlsPeer->is_responder == 0)
18316 {
18317 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018318 tdlsConnInfo_t *tdlsInfo;
18319
18320 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
18321
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018322 if (!vos_timer_is_initialized(
18323 &pTdlsPeer->initiatorWaitTimeoutTimer))
18324 {
18325 /* Initialize initiator wait callback */
18326 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018327 &pTdlsPeer->initiatorWaitTimeoutTimer,
18328 VOS_TIMER_TYPE_SW,
18329 wlan_hdd_tdls_initiator_wait_cb,
18330 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018331 }
Hoonki Lee14621352013-04-16 17:51:19 -070018332 wlan_hdd_tdls_timer_restart(pAdapter,
18333 &pTdlsPeer->initiatorWaitTimeoutTimer,
18334 WAIT_TIME_TDLS_INITIATOR);
18335 /* suspend initiator TX until it receives direct packet from the
18336 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018337 ret = WLANTL_SuspendDataTx(
18338 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18339 &staId, NULL);
18340 if (ret != VOS_STATUS_SUCCESS) {
18341 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
18342 }
Hoonki Lee14621352013-04-16 17:51:19 -070018343 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018344
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018345 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018346 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018347 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018348 suppChannelLen =
18349 tdlsLinkEstablishParams.supportedChannelsLen;
18350
18351 if ((suppChannelLen > 0) &&
18352 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
18353 {
18354 tANI_U8 suppPeerChannel = 0;
18355 int i = 0;
18356 for (i = 0U; i < suppChannelLen; i++)
18357 {
18358 suppPeerChannel =
18359 tdlsLinkEstablishParams.supportedChannels[i];
18360
18361 pTdlsPeer->isOffChannelSupported = FALSE;
18362 if (suppPeerChannel ==
18363 pTdlsPeer->peerParams.channel)
18364 {
18365 pTdlsPeer->isOffChannelSupported = TRUE;
18366 break;
18367 }
18368 }
18369 }
18370 else
18371 {
18372 pTdlsPeer->isOffChannelSupported = FALSE;
18373 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018374 }
18375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18376 "%s: TDLS channel switch request for channel "
18377 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018378 "%d isOffChannelSupported %d", __func__,
18379 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018380 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018381 suppChannelLen,
18382 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018383
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018384 /* TDLS Off Channel, Enable tdls channel switch,
18385 when their is only one tdls link and it supports */
18386 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18387 if ((numCurrTdlsPeers == 1) &&
18388 (TRUE == pTdlsPeer->isOffChannelSupported) &&
18389 (TRUE == pTdlsPeer->isOffChannelConfigured))
18390 {
18391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18392 "%s: Send TDLS channel switch request for channel %d",
18393 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018394
18395 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018396 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
18397 channel = pTdlsPeer->peerParams.channel;
18398
18399 mutex_unlock(&pHddCtx->tdls_lock);
18400
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018401 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
18402 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018403 peerMac,
18404 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018405 TDLS_OFF_CHANNEL_BW_OFFSET,
18406 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018407 if (ret != VOS_STATUS_SUCCESS) {
18408 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
18409 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018410 }
18411 else
18412 {
18413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18414 "%s: TDLS channel switch request not sent"
18415 " numCurrTdlsPeers %d "
18416 "isOffChannelSupported %d "
18417 "isOffChannelConfigured %d",
18418 __func__, numCurrTdlsPeers,
18419 pTdlsPeer->isOffChannelSupported,
18420 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018421 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018422 }
18423
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018424 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018425 else
18426 mutex_unlock(&pHddCtx->tdls_lock);
18427
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018428 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018429
18430 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018431 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18432 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018433 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018434 int ac;
18435 uint8 ucAc[4] = { WLANTL_AC_VO,
18436 WLANTL_AC_VI,
18437 WLANTL_AC_BK,
18438 WLANTL_AC_BE };
18439 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18440 for(ac=0; ac < 4; ac++)
18441 {
18442 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18443 pTdlsPeer->staId, ucAc[ac],
18444 tlTid[ac], tlTid[ac], 0, 0,
18445 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018446 if (status != VOS_STATUS_SUCCESS) {
18447 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18448 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018449 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018450 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018451 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018452
Bhargav Shah66896792015-10-01 18:17:37 +053018453 /* stop TCP delack timer if TDLS is enable */
18454 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18455 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053018456 hdd_wlan_tdls_enable_link_event(peer,
18457 pTdlsPeer->isOffChannelSupported,
18458 pTdlsPeer->isOffChannelConfigured,
18459 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018460 }
18461 break;
18462 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018463 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018464 tANI_U16 numCurrTdlsPeers = 0;
18465 hddTdlsPeer_t *connPeer = NULL;
18466
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018467 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18468 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18469 __func__, MAC_ADDR_ARRAY(peer));
18470
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018471 mutex_lock(&pHddCtx->tdls_lock);
18472 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018473
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018474
Sunil Dutt41de4e22013-11-14 18:09:02 +053018475 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018476 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018477 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18478 " (oper %d) not exsting. ignored",
18479 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18480 return -EINVAL;
18481 }
18482
18483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18484 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18485 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18486 "NL80211_TDLS_DISABLE_LINK");
18487
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018488 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018489 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018490 long status;
18491
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018492 /* set tdls off channel status to false for this peer */
18493 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018494 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18495 eTDLS_LINK_TEARING,
18496 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18497 eTDLS_LINK_UNSPECIFIED:
18498 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018499 mutex_unlock(&pHddCtx->tdls_lock);
18500
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018501 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18502
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018503 status = sme_DeleteTdlsPeerSta(
18504 WLAN_HDD_GET_HAL_CTX(pAdapter),
18505 pAdapter->sessionId, peer );
18506 if (status != VOS_STATUS_SUCCESS) {
18507 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18508 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018509
18510 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18511 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018512
18513 mutex_lock(&pHddCtx->tdls_lock);
18514 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18515 if ( NULL == pTdlsPeer ) {
18516 mutex_unlock(&pHddCtx->tdls_lock);
18517 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18518 " peer was freed in other context",
18519 __func__, MAC_ADDR_ARRAY(peer));
18520 return -EINVAL;
18521 }
18522
Atul Mittal271a7652014-09-12 13:18:22 +053018523 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053018524 eTDLS_LINK_IDLE,
18525 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018526 mutex_unlock(&pHddCtx->tdls_lock);
18527
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018528 if (status <= 0)
18529 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18531 "%s: Del station failed status %ld",
18532 __func__, status);
18533 return -EPERM;
18534 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018535
18536 /* TDLS Off Channel, Enable tdls channel switch,
18537 when their is only one tdls link and it supports */
18538 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18539 if (numCurrTdlsPeers == 1)
18540 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018541 tSirMacAddr peerMac;
18542 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018543
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018544 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018545 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018546
18547 if (connPeer == NULL) {
18548 mutex_unlock(&pHddCtx->tdls_lock);
18549 hddLog(VOS_TRACE_LEVEL_ERROR,
18550 "%s connPeer is NULL", __func__);
18551 return -EINVAL;
18552 }
18553
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018554 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18555 channel = connPeer->peerParams.channel;
18556
18557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18558 "%s: TDLS channel switch "
18559 "isOffChannelSupported %d "
18560 "isOffChannelConfigured %d "
18561 "isOffChannelEstablished %d",
18562 __func__,
18563 (connPeer ? connPeer->isOffChannelSupported : -1),
18564 (connPeer ? connPeer->isOffChannelConfigured : -1),
18565 (connPeer ? connPeer->isOffChannelEstablished : -1));
18566
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018567 if ((connPeer) &&
18568 (connPeer->isOffChannelSupported == TRUE) &&
18569 (connPeer->isOffChannelConfigured == TRUE))
18570 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018571 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018572 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018573 status = sme_SendTdlsChanSwitchReq(
18574 WLAN_HDD_GET_HAL_CTX(pAdapter),
18575 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018576 peerMac,
18577 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018578 TDLS_OFF_CHANNEL_BW_OFFSET,
18579 TDLS_CHANNEL_SWITCH_ENABLE);
18580 if (status != VOS_STATUS_SUCCESS) {
18581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18582 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018583 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018584 else
18585 mutex_unlock(&pHddCtx->tdls_lock);
18586 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018587 else
18588 {
18589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18590 "%s: TDLS channel switch request not sent "
18591 "numCurrTdlsPeers %d ",
18592 __func__, numCurrTdlsPeers);
18593 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018594 }
18595 else
18596 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018597 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18599 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080018600 }
Bhargav Shah66896792015-10-01 18:17:37 +053018601 if (numCurrTdlsPeers == 0) {
18602 /* start TCP delack timer if TDLS is disable */
18603 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18604 hdd_manage_delack_timer(pHddCtx);
18605 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018606 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018607 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018608 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018609 {
Atul Mittal115287b2014-07-08 13:26:33 +053018610 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018611
Atul Mittal115287b2014-07-08 13:26:33 +053018612 if (0 != status)
18613 {
18614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018615 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053018616 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018617 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053018618 break;
18619 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018620 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018621 {
Atul Mittal115287b2014-07-08 13:26:33 +053018622 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
18623 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018624 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053018625 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018626
Atul Mittal115287b2014-07-08 13:26:33 +053018627 if (0 != status)
18628 {
18629 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018630 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053018631 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053018632 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053018633 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018634 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018635 case NL80211_TDLS_DISCOVERY_REQ:
18636 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018638 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018639 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018640 return -ENOTSUPP;
18641 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18643 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018644 return -ENOTSUPP;
18645 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018646
18647 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018648 return 0;
18649}
Chilam NG571c65a2013-01-19 12:27:36 +053018650
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018651static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018652#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18653 const u8 *peer,
18654#else
18655 u8 *peer,
18656#endif
18657 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018658{
18659 int ret;
18660
18661 vos_ssr_protect(__func__);
18662 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
18663 vos_ssr_unprotect(__func__);
18664
18665 return ret;
18666}
18667
Chilam NG571c65a2013-01-19 12:27:36 +053018668int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
18669 struct net_device *dev, u8 *peer)
18670{
Arif Hussaina7c8e412013-11-20 11:06:42 -080018671 hddLog(VOS_TRACE_LEVEL_INFO,
18672 "tdls send discover req: "MAC_ADDRESS_STR,
18673 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018674#if TDLS_MGMT_VERSION2
18675 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18676 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18677#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018678#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18679 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18680 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
18681#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18682 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18683 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18684#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18685 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18686 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18687#else
Chilam NG571c65a2013-01-19 12:27:36 +053018688 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18689 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018690#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018691#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053018692}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018693#endif
18694
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018695#ifdef WLAN_FEATURE_GTK_OFFLOAD
18696/*
18697 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
18698 * Callback rountine called upon receiving response for
18699 * get offload info
18700 */
18701void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
18702 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
18703{
18704
18705 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018706 tANI_U8 tempReplayCounter[8];
18707 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018708
18709 ENTER();
18710
18711 if (NULL == pAdapter)
18712 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018714 "%s: HDD adapter is Null", __func__);
18715 return ;
18716 }
18717
18718 if (NULL == pGtkOffloadGetInfoRsp)
18719 {
18720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18721 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
18722 return ;
18723 }
18724
18725 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
18726 {
18727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18728 "%s: wlan Failed to get replay counter value",
18729 __func__);
18730 return ;
18731 }
18732
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018733 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18734 /* Update replay counter */
18735 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
18736 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18737
18738 {
18739 /* changing from little to big endian since supplicant
18740 * works on big endian format
18741 */
18742 int i;
18743 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18744
18745 for (i = 0; i < 8; i++)
18746 {
18747 tempReplayCounter[7-i] = (tANI_U8)p[i];
18748 }
18749 }
18750
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018751 /* Update replay counter to NL */
18752 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018753 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018754}
18755
18756/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018757 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018758 * This function is used to offload GTK rekeying job to the firmware.
18759 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018760int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018761 struct cfg80211_gtk_rekey_data *data)
18762{
18763 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18764 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18765 hdd_station_ctx_t *pHddStaCtx;
18766 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018767 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018768 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018769 eHalStatus status = eHAL_STATUS_FAILURE;
18770
18771 ENTER();
18772
18773 if (NULL == pAdapter)
18774 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018775 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018776 "%s: HDD adapter is Null", __func__);
18777 return -ENODEV;
18778 }
18779
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018780 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18781 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
18782 pAdapter->sessionId, pAdapter->device_mode));
18783
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018784 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018785 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018786 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018787 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018788 }
18789
18790 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18791 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18792 if (NULL == hHal)
18793 {
18794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18795 "%s: HAL context is Null!!!", __func__);
18796 return -EAGAIN;
18797 }
18798
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018799 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
18800 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
18801 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
18802 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018803 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018804 {
18805 /* changing from big to little endian since driver
18806 * works on little endian format
18807 */
18808 tANI_U8 *p =
18809 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
18810 int i;
18811
18812 for (i = 0; i < 8; i++)
18813 {
18814 p[7-i] = data->replay_ctr[i];
18815 }
18816 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018817
18818 if (TRUE == pHddCtx->hdd_wlan_suspended)
18819 {
18820 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018821 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
18822 sizeof (tSirGtkOffloadParams));
18823 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018824 pAdapter->sessionId);
18825
18826 if (eHAL_STATUS_SUCCESS != status)
18827 {
18828 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18829 "%s: sme_SetGTKOffload failed, returned %d",
18830 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018831
18832 /* Need to clear any trace of key value in the memory.
18833 * Thus zero out the memory even though it is local
18834 * variable.
18835 */
18836 vos_mem_zero(&hddGtkOffloadReqParams,
18837 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018838 return status;
18839 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018840 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18841 "%s: sme_SetGTKOffload successfull", __func__);
18842 }
18843 else
18844 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018845 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18846 "%s: wlan not suspended GTKOffload request is stored",
18847 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018848 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018849
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018850 /* Need to clear any trace of key value in the memory.
18851 * Thus zero out the memory even though it is local
18852 * variable.
18853 */
18854 vos_mem_zero(&hddGtkOffloadReqParams,
18855 sizeof(hddGtkOffloadReqParams));
18856
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018857 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018858 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018859}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018860
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018861int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
18862 struct cfg80211_gtk_rekey_data *data)
18863{
18864 int ret;
18865
18866 vos_ssr_protect(__func__);
18867 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
18868 vos_ssr_unprotect(__func__);
18869
18870 return ret;
18871}
18872#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018873/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018874 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018875 * This function is used to set access control policy
18876 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018877static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18878 struct net_device *dev,
18879 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018880{
18881 int i;
18882 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18883 hdd_hostapd_state_t *pHostapdState;
18884 tsap_Config_t *pConfig;
18885 v_CONTEXT_t pVosContext = NULL;
18886 hdd_context_t *pHddCtx;
18887 int status;
18888
18889 ENTER();
18890
18891 if (NULL == pAdapter)
18892 {
18893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18894 "%s: HDD adapter is Null", __func__);
18895 return -ENODEV;
18896 }
18897
18898 if (NULL == params)
18899 {
18900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18901 "%s: params is Null", __func__);
18902 return -EINVAL;
18903 }
18904
18905 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18906 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018907 if (0 != status)
18908 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018909 return status;
18910 }
18911
18912 pVosContext = pHddCtx->pvosContext;
18913 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
18914
18915 if (NULL == pHostapdState)
18916 {
18917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18918 "%s: pHostapdState is Null", __func__);
18919 return -EINVAL;
18920 }
18921
18922 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
18923 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018924 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18925 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
18926 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018927
18928 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
18929 {
18930 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
18931
18932 /* default value */
18933 pConfig->num_accept_mac = 0;
18934 pConfig->num_deny_mac = 0;
18935
18936 /**
18937 * access control policy
18938 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
18939 * listed in hostapd.deny file.
18940 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
18941 * listed in hostapd.accept file.
18942 */
18943 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
18944 {
18945 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
18946 }
18947 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
18948 {
18949 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
18950 }
18951 else
18952 {
18953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18954 "%s:Acl Policy : %d is not supported",
18955 __func__, params->acl_policy);
18956 return -ENOTSUPP;
18957 }
18958
18959 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
18960 {
18961 pConfig->num_accept_mac = params->n_acl_entries;
18962 for (i = 0; i < params->n_acl_entries; i++)
18963 {
18964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18965 "** Add ACL MAC entry %i in WhiletList :"
18966 MAC_ADDRESS_STR, i,
18967 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18968
18969 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
18970 sizeof(qcmacaddr));
18971 }
18972 }
18973 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
18974 {
18975 pConfig->num_deny_mac = params->n_acl_entries;
18976 for (i = 0; i < params->n_acl_entries; i++)
18977 {
18978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18979 "** Add ACL MAC entry %i in BlackList :"
18980 MAC_ADDRESS_STR, i,
18981 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18982
18983 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
18984 sizeof(qcmacaddr));
18985 }
18986 }
18987
18988 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
18989 {
18990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18991 "%s: SAP Set Mac Acl fail", __func__);
18992 return -EINVAL;
18993 }
18994 }
18995 else
18996 {
18997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053018998 "%s: Invalid device_mode = %s (%d)",
18999 __func__, hdd_device_modetoString(pAdapter->device_mode),
19000 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019001 return -EINVAL;
19002 }
19003
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019004 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019005 return 0;
19006}
19007
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019008static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19009 struct net_device *dev,
19010 const struct cfg80211_acl_data *params)
19011{
19012 int ret;
19013 vos_ssr_protect(__func__);
19014 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
19015 vos_ssr_unprotect(__func__);
19016
19017 return ret;
19018}
19019
Leo Chang9056f462013-08-01 19:21:11 -070019020#ifdef WLAN_NL80211_TESTMODE
19021#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070019022void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070019023(
19024 void *pAdapter,
19025 void *indCont
19026)
19027{
Leo Changd9df8aa2013-09-26 13:32:26 -070019028 tSirLPHBInd *lphbInd;
19029 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053019030 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070019031
19032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019033 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070019034
c_hpothu73f35e62014-04-18 13:40:08 +053019035 if (pAdapter == NULL)
19036 {
19037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19038 "%s: pAdapter is NULL\n",__func__);
19039 return;
19040 }
19041
Leo Chang9056f462013-08-01 19:21:11 -070019042 if (NULL == indCont)
19043 {
19044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019045 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070019046 return;
19047 }
19048
c_hpothu73f35e62014-04-18 13:40:08 +053019049 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070019050 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070019051 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053019052 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070019053 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070019054 GFP_ATOMIC);
19055 if (!skb)
19056 {
19057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19058 "LPHB timeout, NL buffer alloc fail");
19059 return;
19060 }
19061
Leo Changac3ba772013-10-07 09:47:04 -070019062 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070019063 {
19064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19065 "WLAN_HDD_TM_ATTR_CMD put fail");
19066 goto nla_put_failure;
19067 }
Leo Changac3ba772013-10-07 09:47:04 -070019068 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070019069 {
19070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19071 "WLAN_HDD_TM_ATTR_TYPE put fail");
19072 goto nla_put_failure;
19073 }
Leo Changac3ba772013-10-07 09:47:04 -070019074 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070019075 sizeof(tSirLPHBInd), lphbInd))
19076 {
19077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19078 "WLAN_HDD_TM_ATTR_DATA put fail");
19079 goto nla_put_failure;
19080 }
Leo Chang9056f462013-08-01 19:21:11 -070019081 cfg80211_testmode_event(skb, GFP_ATOMIC);
19082 return;
19083
19084nla_put_failure:
19085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19086 "NLA Put fail");
19087 kfree_skb(skb);
19088
19089 return;
19090}
19091#endif /* FEATURE_WLAN_LPHB */
19092
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019093static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070019094{
19095 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
19096 int err = 0;
19097#ifdef FEATURE_WLAN_LPHB
19098 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070019099 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019100
19101 ENTER();
19102
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019103 err = wlan_hdd_validate_context(pHddCtx);
19104 if (0 != err)
19105 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019106 return err;
19107 }
Leo Chang9056f462013-08-01 19:21:11 -070019108#endif /* FEATURE_WLAN_LPHB */
19109
19110 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
19111 if (err)
19112 {
19113 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19114 "%s Testmode INV ATTR", __func__);
19115 return err;
19116 }
19117
19118 if (!tb[WLAN_HDD_TM_ATTR_CMD])
19119 {
19120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19121 "%s Testmode INV CMD", __func__);
19122 return -EINVAL;
19123 }
19124
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019125 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19126 TRACE_CODE_HDD_CFG80211_TESTMODE,
19127 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070019128 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
19129 {
19130#ifdef FEATURE_WLAN_LPHB
19131 /* Low Power Heartbeat configuration request */
19132 case WLAN_HDD_TM_CMD_WLAN_HB:
19133 {
19134 int buf_len;
19135 void *buf;
19136 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080019137 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070019138
19139 if (!tb[WLAN_HDD_TM_ATTR_DATA])
19140 {
19141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19142 "%s Testmode INV DATA", __func__);
19143 return -EINVAL;
19144 }
19145
19146 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
19147 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080019148
19149 hb_params_temp =(tSirLPHBReq *)buf;
19150 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
19151 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
19152 return -EINVAL;
19153
Leo Chang9056f462013-08-01 19:21:11 -070019154 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
19155 if (NULL == hb_params)
19156 {
19157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19158 "%s Request Buffer Alloc Fail", __func__);
19159 return -EINVAL;
19160 }
19161
19162 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070019163 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
19164 hb_params,
19165 wlan_hdd_cfg80211_lphb_ind_handler);
19166 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070019167 {
Leo Changd9df8aa2013-09-26 13:32:26 -070019168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19169 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070019170 vos_mem_free(hb_params);
19171 }
Leo Chang9056f462013-08-01 19:21:11 -070019172 return 0;
19173 }
19174#endif /* FEATURE_WLAN_LPHB */
19175 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19177 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070019178 return -EOPNOTSUPP;
19179 }
19180
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019181 EXIT();
19182 return err;
Leo Chang9056f462013-08-01 19:21:11 -070019183}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019184
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053019185static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
19186#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
19187 struct wireless_dev *wdev,
19188#endif
19189 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019190{
19191 int ret;
19192
19193 vos_ssr_protect(__func__);
19194 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
19195 vos_ssr_unprotect(__func__);
19196
19197 return ret;
19198}
Leo Chang9056f462013-08-01 19:21:11 -070019199#endif /* CONFIG_NL80211_TESTMODE */
19200
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019201static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019202 struct net_device *dev,
19203 int idx, struct survey_info *survey)
19204{
19205 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19206 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053019207 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019208 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053019209 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019210 v_S7_t snr,rssi;
19211 int status, i, j, filled = 0;
19212
19213 ENTER();
19214
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019215 if (NULL == pAdapter)
19216 {
19217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19218 "%s: HDD adapter is Null", __func__);
19219 return -ENODEV;
19220 }
19221
19222 if (NULL == wiphy)
19223 {
19224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19225 "%s: wiphy is Null", __func__);
19226 return -ENODEV;
19227 }
19228
19229 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19230 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019231 if (0 != status)
19232 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019233 return status;
19234 }
19235
Mihir Sheted9072e02013-08-21 17:02:29 +053019236 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19237
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019238 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053019239 0 != pAdapter->survey_idx ||
19240 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019241 {
19242 /* The survey dump ops when implemented completely is expected to
19243 * return a survey of all channels and the ops is called by the
19244 * kernel with incremental values of the argument 'idx' till it
19245 * returns -ENONET. But we can only support the survey for the
19246 * operating channel for now. survey_idx is used to track
19247 * that the ops is called only once and then return -ENONET for
19248 * the next iteration
19249 */
19250 pAdapter->survey_idx = 0;
19251 return -ENONET;
19252 }
19253
Mukul Sharma9d5233b2015-06-11 20:28:20 +053019254 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
19255 {
19256 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19257 "%s: Roaming in progress, hence return ", __func__);
19258 return -ENONET;
19259 }
19260
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019261 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19262
19263 wlan_hdd_get_snr(pAdapter, &snr);
19264 wlan_hdd_get_rssi(pAdapter, &rssi);
19265
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019266 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19267 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
19268 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019269 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
19270 hdd_wlan_get_freq(channel, &freq);
19271
19272
19273 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
19274 {
19275 if (NULL == wiphy->bands[i])
19276 {
19277 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
19278 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
19279 continue;
19280 }
19281
19282 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
19283 {
19284 struct ieee80211_supported_band *band = wiphy->bands[i];
19285
19286 if (band->channels[j].center_freq == (v_U16_t)freq)
19287 {
19288 survey->channel = &band->channels[j];
19289 /* The Rx BDs contain SNR values in dB for the received frames
19290 * while the supplicant expects noise. So we calculate and
19291 * return the value of noise (dBm)
19292 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
19293 */
19294 survey->noise = rssi - snr;
19295 survey->filled = SURVEY_INFO_NOISE_DBM;
19296 filled = 1;
19297 }
19298 }
19299 }
19300
19301 if (filled)
19302 pAdapter->survey_idx = 1;
19303 else
19304 {
19305 pAdapter->survey_idx = 0;
19306 return -ENONET;
19307 }
19308
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019309 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019310 return 0;
19311}
19312
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019313static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
19314 struct net_device *dev,
19315 int idx, struct survey_info *survey)
19316{
19317 int ret;
19318
19319 vos_ssr_protect(__func__);
19320 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
19321 vos_ssr_unprotect(__func__);
19322
19323 return ret;
19324}
19325
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019326/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019327 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019328 * this is called when cfg80211 driver resume
19329 * driver updates latest sched_scan scan result(if any) to cfg80211 database
19330 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019331int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019332{
19333 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19334 hdd_adapter_t *pAdapter;
19335 hdd_adapter_list_node_t *pAdapterNode, *pNext;
19336 VOS_STATUS status = VOS_STATUS_SUCCESS;
19337
19338 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019339
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019340 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019341 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019342 return 0;
19343 }
19344
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019345 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
19346 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019347 spin_lock(&pHddCtx->schedScan_lock);
19348 pHddCtx->isWiphySuspended = FALSE;
19349 if (TRUE != pHddCtx->isSchedScanUpdatePending)
19350 {
19351 spin_unlock(&pHddCtx->schedScan_lock);
19352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19353 "%s: Return resume is not due to PNO indication", __func__);
19354 return 0;
19355 }
19356 // Reset flag to avoid updatating cfg80211 data old results again
19357 pHddCtx->isSchedScanUpdatePending = FALSE;
19358 spin_unlock(&pHddCtx->schedScan_lock);
19359
19360 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
19361
19362 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
19363 {
19364 pAdapter = pAdapterNode->pAdapter;
19365 if ( (NULL != pAdapter) &&
19366 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
19367 {
19368 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019369 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19371 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019372 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019373 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019374 {
19375 /* Acquire wakelock to handle the case where APP's tries to
19376 * suspend immediately after updating the scan results. Whis
19377 * results in app's is in suspended state and not able to
19378 * process the connect request to AP
19379 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053019380 hdd_prevent_suspend_timeout(2000,
19381 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019382 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019383 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019384
19385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19386 "%s : cfg80211 scan result database updated", __func__);
19387
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019388 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019389 return 0;
19390
19391 }
19392 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19393 pAdapterNode = pNext;
19394 }
19395
19396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19397 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019398 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019399 return 0;
19400}
19401
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019402int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
19403{
19404 int ret;
19405
19406 vos_ssr_protect(__func__);
19407 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
19408 vos_ssr_unprotect(__func__);
19409
19410 return ret;
19411}
19412
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019413/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019414 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019415 * this is called when cfg80211 driver suspends
19416 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019417int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019418 struct cfg80211_wowlan *wow)
19419{
19420 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019421 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019422
19423 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019424
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019425 ret = wlan_hdd_validate_context(pHddCtx);
19426 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019427 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019428 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019429 }
19430
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019431
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019432 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19433 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
19434 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019435 pHddCtx->isWiphySuspended = TRUE;
19436
19437 EXIT();
19438
19439 return 0;
19440}
19441
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019442int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19443 struct cfg80211_wowlan *wow)
19444{
19445 int ret;
19446
19447 vos_ssr_protect(__func__);
19448 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19449 vos_ssr_unprotect(__func__);
19450
19451 return ret;
19452}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019453
19454#ifdef FEATURE_OEM_DATA_SUPPORT
19455static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019456 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019457{
19458 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19459
19460 ENTER();
19461
19462 if (wlan_hdd_validate_context(pHddCtx)) {
19463 return;
19464 }
19465 if (!pMsg)
19466 {
19467 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
19468 return;
19469 }
19470
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019471 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019472
19473 EXIT();
19474 return;
19475
19476}
19477
19478void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019479 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019480{
19481 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19482
19483 ENTER();
19484
19485 if (wlan_hdd_validate_context(pHddCtx)) {
19486 return;
19487 }
19488
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019489 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019490
19491 switch(evType) {
19492 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019493 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019494 break;
19495 default:
19496 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
19497 break;
19498 }
19499 EXIT();
19500}
19501#endif
19502
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019503#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19504 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019505/**
19506 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
19507 * @wiphy: Pointer to wiphy
19508 * @wdev: Pointer to wireless device structure
19509 *
19510 * This function is used to abort an ongoing scan
19511 *
19512 * Return: None
19513 */
19514static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19515 struct wireless_dev *wdev)
19516{
19517 struct net_device *dev = wdev->netdev;
19518 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
19519 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
19520 int ret;
19521
19522 ENTER();
19523
19524 if (NULL == adapter) {
19525 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
19526 return;
19527 }
19528
19529 ret = wlan_hdd_validate_context(hdd_ctx);
19530 if (0 != ret)
19531 return;
19532
19533 wlan_hdd_scan_abort(adapter);
19534
19535 return;
19536}
19537
19538/**
19539 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
19540 * @wiphy: Pointer to wiphy
19541 * @wdev: Pointer to wireless device structure
19542 *
19543 * Return: None
19544 */
19545void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19546 struct wireless_dev *wdev)
19547{
19548 vos_ssr_protect(__func__);
19549 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
19550 vos_ssr_unprotect(__func__);
19551
19552 return;
19553}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019554#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019555
Jeff Johnson295189b2012-06-20 16:38:30 -070019556/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019557static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070019558{
19559 .add_virtual_intf = wlan_hdd_add_virtual_intf,
19560 .del_virtual_intf = wlan_hdd_del_virtual_intf,
19561 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
19562 .change_station = wlan_hdd_change_station,
19563#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
19564 .add_beacon = wlan_hdd_cfg80211_add_beacon,
19565 .del_beacon = wlan_hdd_cfg80211_del_beacon,
19566 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019567#else
19568 .start_ap = wlan_hdd_cfg80211_start_ap,
19569 .change_beacon = wlan_hdd_cfg80211_change_beacon,
19570 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070019571#endif
19572 .change_bss = wlan_hdd_cfg80211_change_bss,
19573 .add_key = wlan_hdd_cfg80211_add_key,
19574 .get_key = wlan_hdd_cfg80211_get_key,
19575 .del_key = wlan_hdd_cfg80211_del_key,
19576 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019577#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070019578 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019579#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019580 .scan = wlan_hdd_cfg80211_scan,
19581 .connect = wlan_hdd_cfg80211_connect,
19582 .disconnect = wlan_hdd_cfg80211_disconnect,
19583 .join_ibss = wlan_hdd_cfg80211_join_ibss,
19584 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
19585 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
19586 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
19587 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070019588 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
19589 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053019590 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070019591#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19592 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
19593 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
19594 .set_txq_params = wlan_hdd_set_txq_params,
19595#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019596 .get_station = wlan_hdd_cfg80211_get_station,
19597 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
19598 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019599 .add_station = wlan_hdd_cfg80211_add_station,
19600#ifdef FEATURE_WLAN_LFR
19601 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
19602 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
19603 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
19604#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019605#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
19606 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
19607#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019608#ifdef FEATURE_WLAN_TDLS
19609 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
19610 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
19611#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019612#ifdef WLAN_FEATURE_GTK_OFFLOAD
19613 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
19614#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019615#ifdef FEATURE_WLAN_SCAN_PNO
19616 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
19617 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
19618#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019619 .resume = wlan_hdd_cfg80211_resume_wlan,
19620 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019621 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070019622#ifdef WLAN_NL80211_TESTMODE
19623 .testmode_cmd = wlan_hdd_cfg80211_testmode,
19624#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019625 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019626#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19627 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019628 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019629#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019630};
19631