blob: d8667277e35ba2e8a231a456c3117f3935792c0d [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 /*
2726 * Firmware returns timestamp from WiFi turn ON till
2727 * BSSID was cached (in seconds). Add this with
2728 * time gap between system boot up to WiFi turn ON
2729 * to derive the time since boot when the
2730 * BSSID was cached.
2731 */
2732 pSirWifiScanResult->ts += pHddCtx->wifi_turn_on_time_since_boot;
2733 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2734 "Ssid (%s)"
2735 "Bssid: %pM "
2736 "Channel (%u)"
2737 "Rssi (%d)"
2738 "RTT (%u)"
2739 "RTT_SD (%u)"
2740 "Beacon Period %u"
2741 "Capability 0x%x "
2742 "Ie length %d",
2743 i,
2744 pSirWifiScanResult->ts,
2745 pSirWifiScanResult->ssid,
2746 pSirWifiScanResult->bssid,
2747 pSirWifiScanResult->channel,
2748 pSirWifiScanResult->rssi,
2749 pSirWifiScanResult->rtt,
2750 pSirWifiScanResult->rtt_sd,
2751 pSirWifiScanResult->beaconPeriod,
2752 pSirWifiScanResult->capability,
2753 ieLength);
2754
2755 ap = nla_nest_start(skb, j + 1);
2756 if (!ap)
2757 {
2758 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2759 goto fail;
2760 }
2761
2762 if (nla_put_u64(skb,
2763 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2764 pSirWifiScanResult->ts) )
2765 {
2766 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2767 goto fail;
2768 }
2769 if (nla_put(skb,
2770 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2771 sizeof(pSirWifiScanResult->ssid),
2772 pSirWifiScanResult->ssid) )
2773 {
2774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2775 goto fail;
2776 }
2777 if (nla_put(skb,
2778 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2779 sizeof(pSirWifiScanResult->bssid),
2780 pSirWifiScanResult->bssid) )
2781 {
2782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2783 goto fail;
2784 }
2785 if (nla_put_u32(skb,
2786 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2787 pSirWifiScanResult->channel) )
2788 {
2789 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2790 goto fail;
2791 }
2792 if (nla_put_s32(skb,
2793 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2794 pSirWifiScanResult->rssi) )
2795 {
2796 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2797 goto fail;
2798 }
2799 if (nla_put_u32(skb,
2800 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2801 pSirWifiScanResult->rtt) )
2802 {
2803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2804 goto fail;
2805 }
2806 if (nla_put_u32(skb,
2807 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2808 pSirWifiScanResult->rtt_sd))
2809 {
2810 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2811 goto fail;
2812 }
2813 if (nla_put_u32(skb,
2814 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2815 pSirWifiScanResult->beaconPeriod))
2816 {
2817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2818 goto fail;
2819 }
2820 if (nla_put_u32(skb,
2821 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2822 pSirWifiScanResult->capability))
2823 {
2824 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2825 goto fail;
2826 }
2827 if (nla_put_u32(skb,
2828 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2829 ieLength))
2830 {
2831 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2832 goto fail;
2833 }
2834
2835 if (ieLength)
2836 if (nla_put(skb,
2837 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2838 ieLength, ie)) {
2839 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2840 goto fail;
2841 }
2842
2843 nla_nest_end(skb, ap);
2844 }
2845 nla_nest_end(skb, aps);
2846 nla_nest_end(skb, nla_result);
2847 }
2848
2849 nla_nest_end(skb, nla_results);
2850
2851 cfg80211_vendor_cmd_reply(skb);
2852
2853 } while (totalResults > 0);
2854 }
2855
2856 if (!pData->moreData) {
2857 spin_lock(&hdd_context_lock);
2858 context->response_status = 0;
2859 complete(&context->response_event);
2860 spin_unlock(&hdd_context_lock);
2861 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302862
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302863 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302864 return;
2865fail:
2866 kfree_skb(skb);
2867 return;
2868}
2869
2870static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2871 void *pMsg)
2872{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302873 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302874 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2875 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302876 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302877
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302878 ENTER();
2879
2880 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302881 hddLog(LOGE,
2882 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302883 return;
2884 }
2885 if (!pMsg)
2886 {
2887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302888 return;
2889 }
2890
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302891 if (pData->bss_found)
2892 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2893 else
2894 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2895
Dino Mycle6fb96c12014-06-10 11:52:40 +05302896 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302897#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2898 NULL,
2899#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302900 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302901 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302902
2903 if (!skb) {
2904 hddLog(VOS_TRACE_LEVEL_ERROR,
2905 FL("cfg80211_vendor_event_alloc failed"));
2906 return;
2907 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302908
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302909 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2910 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2911 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2912 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2913
2914 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302915 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2916 "Ssid (%s) "
2917 "Bssid (" MAC_ADDRESS_STR ") "
2918 "Channel (%u) "
2919 "Rssi (%d) "
2920 "RTT (%u) "
2921 "RTT_SD (%u) ",
2922 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302923 pData->bssHotlist[i].ts,
2924 pData->bssHotlist[i].ssid,
2925 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2926 pData->bssHotlist[i].channel,
2927 pData->bssHotlist[i].rssi,
2928 pData->bssHotlist[i].rtt,
2929 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302930 }
2931
2932 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2933 pData->requestId) ||
2934 nla_put_u32(skb,
2935 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302936 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302937 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2938 goto fail;
2939 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302940 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302941 struct nlattr *aps;
2942
2943 aps = nla_nest_start(skb,
2944 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2945 if (!aps)
2946 goto fail;
2947
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302948 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302949 struct nlattr *ap;
2950
2951 ap = nla_nest_start(skb, i + 1);
2952 if (!ap)
2953 goto fail;
2954
2955 if (nla_put_u64(skb,
2956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302957 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302958 nla_put(skb,
2959 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302960 sizeof(pData->bssHotlist[i].ssid),
2961 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302962 nla_put(skb,
2963 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302964 sizeof(pData->bssHotlist[i].bssid),
2965 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302966 nla_put_u32(skb,
2967 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302968 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302969 nla_put_s32(skb,
2970 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302971 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302972 nla_put_u32(skb,
2973 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302974 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302975 nla_put_u32(skb,
2976 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302977 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302978 goto fail;
2979
2980 nla_nest_end(skb, ap);
2981 }
2982 nla_nest_end(skb, aps);
2983
2984 if (nla_put_u8(skb,
2985 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2986 pData->moreData))
2987 goto fail;
2988 }
2989
2990 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302991 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302992 return;
2993
2994fail:
2995 kfree_skb(skb);
2996 return;
2997
2998}
Dino Mycle6fb96c12014-06-10 11:52:40 +05302999
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303000/**
3001 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
3002 * Handle an SSID hotlist match event
3003 * @ctx: HDD context registered with SME
3004 * @event: The SSID hotlist match event
3005 *
3006 * This function will take an SSID match event that was generated by
3007 * firmware and will convert it into a cfg80211 vendor event which is
3008 * sent to userspace.
3009 *
3010 * Return: none
3011 */
3012static void
3013wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
3014 void *pMsg)
3015{
3016 hdd_context_t *hdd_ctx = ctx;
3017 struct sk_buff *skb;
3018 tANI_U32 i, index;
3019 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3020
3021 ENTER();
3022
3023 if (wlan_hdd_validate_context(hdd_ctx)) {
3024 hddLog(LOGE,
3025 FL("HDD context is not valid or response"));
3026 return;
3027 }
3028 if (!pMsg)
3029 {
3030 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3031 return;
3032 }
3033
3034 if (pData->ssid_found) {
3035 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3036 hddLog(LOG1, "SSID hotlist found");
3037 } else {
3038 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3039 hddLog(LOG1, "SSID hotlist lost");
3040 }
3041
3042 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3043#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3044 NULL,
3045#endif
3046 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3047 index, GFP_KERNEL);
3048
3049 if (!skb) {
3050 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3051 return;
3052 }
3053 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3054 pData->requestId, pData->numHotlistSsid, pData->moreData);
3055
3056 for (i = 0; i < pData->numHotlistSsid; i++) {
3057 hddLog(LOG1, "[i=%d] Timestamp %llu "
3058 "Ssid: %s "
3059 "Bssid (" MAC_ADDRESS_STR ") "
3060 "Channel %u "
3061 "Rssi %d "
3062 "RTT %u "
3063 "RTT_SD %u",
3064 i,
3065 pData->ssidHotlist[i].ts,
3066 pData->ssidHotlist[i].ssid,
3067 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3068 pData->ssidHotlist[i].channel,
3069 pData->ssidHotlist[i].rssi,
3070 pData->ssidHotlist[i].rtt,
3071 pData->ssidHotlist[i].rtt_sd);
3072 }
3073
3074 if (nla_put_u32(skb,
3075 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3076 pData->requestId) ||
3077 nla_put_u32(skb,
3078 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3079 pData->numHotlistSsid)) {
3080 hddLog(LOGE, FL("put fail"));
3081 goto fail;
3082 }
3083
3084 if (pData->numHotlistSsid) {
3085 struct nlattr *aps;
3086 aps = nla_nest_start(skb,
3087 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3088 if (!aps) {
3089 hddLog(LOGE, FL("nest fail"));
3090 goto fail;
3091 }
3092
3093 for (i = 0; i < pData->numHotlistSsid; i++) {
3094 struct nlattr *ap;
3095
3096 ap = nla_nest_start(skb, i);
3097 if (!ap) {
3098 hddLog(LOGE, FL("nest fail"));
3099 goto fail;
3100 }
3101
3102 if (nla_put_u64(skb,
3103 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3104 pData->ssidHotlist[i].ts) ||
3105 nla_put(skb,
3106 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3107 sizeof(pData->ssidHotlist[i].ssid),
3108 pData->ssidHotlist[i].ssid) ||
3109 nla_put(skb,
3110 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3111 sizeof(pData->ssidHotlist[i].bssid),
3112 pData->ssidHotlist[i].bssid) ||
3113 nla_put_u32(skb,
3114 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3115 pData->ssidHotlist[i].channel) ||
3116 nla_put_s32(skb,
3117 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3118 pData->ssidHotlist[i].rssi) ||
3119 nla_put_u32(skb,
3120 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3121 pData->ssidHotlist[i].rtt) ||
3122 nla_put_u32(skb,
3123 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3124 pData->ssidHotlist[i].rtt_sd)) {
3125 hddLog(LOGE, FL("put fail"));
3126 goto fail;
3127 }
3128 nla_nest_end(skb, ap);
3129 }
3130 nla_nest_end(skb, aps);
3131
3132 if (nla_put_u8(skb,
3133 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3134 pData->moreData)) {
3135 hddLog(LOGE, FL("put fail"));
3136 goto fail;
3137 }
3138 }
3139
3140 cfg80211_vendor_event(skb, GFP_KERNEL);
3141 return;
3142
3143fail:
3144 kfree_skb(skb);
3145 return;
3146
3147}
3148
3149
Dino Mycle6fb96c12014-06-10 11:52:40 +05303150static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3151 void *pMsg)
3152{
3153 struct sk_buff *skb;
3154 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3155 tpSirWifiFullScanResultEvent pData =
3156 (tpSirWifiFullScanResultEvent) (pMsg);
3157
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303158 ENTER();
3159
3160 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303161 hddLog(LOGE,
3162 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303163 return;
3164 }
3165 if (!pMsg)
3166 {
3167 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303168 return;
3169 }
3170
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303171 /*
3172 * If the full scan result including IE data exceeds NL 4K size
3173 * limitation, drop that beacon/probe rsp frame.
3174 */
3175 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3176 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3177 return;
3178 }
3179
Dino Mycle6fb96c12014-06-10 11:52:40 +05303180 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303181#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3182 NULL,
3183#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303184 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3185 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3186 GFP_KERNEL);
3187
3188 if (!skb) {
3189 hddLog(VOS_TRACE_LEVEL_ERROR,
3190 FL("cfg80211_vendor_event_alloc failed"));
3191 return;
3192 }
3193
Dino Mycle6fb96c12014-06-10 11:52:40 +05303194 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3195 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3196 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3197 "Ssid (%s)"
3198 "Bssid (" MAC_ADDRESS_STR ")"
3199 "Channel (%u)"
3200 "Rssi (%d)"
3201 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303202 "RTT_SD (%u)"
3203 "Bcn Period %d"
3204 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303205 pData->ap.ts,
3206 pData->ap.ssid,
3207 MAC_ADDR_ARRAY(pData->ap.bssid),
3208 pData->ap.channel,
3209 pData->ap.rssi,
3210 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303211 pData->ap.rtt_sd,
3212 pData->ap.beaconPeriod,
3213 pData->ap.capability);
3214
Dino Mycle6fb96c12014-06-10 11:52:40 +05303215 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3216 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3217 pData->requestId) ||
3218 nla_put_u64(skb,
3219 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3220 pData->ap.ts) ||
3221 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3222 sizeof(pData->ap.ssid),
3223 pData->ap.ssid) ||
3224 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3225 WNI_CFG_BSSID_LEN,
3226 pData->ap.bssid) ||
3227 nla_put_u32(skb,
3228 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3229 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303230 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303231 pData->ap.rssi) ||
3232 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3233 pData->ap.rtt) ||
3234 nla_put_u32(skb,
3235 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3236 pData->ap.rtt_sd) ||
3237 nla_put_u16(skb,
3238 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3239 pData->ap.beaconPeriod) ||
3240 nla_put_u16(skb,
3241 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3242 pData->ap.capability) ||
3243 nla_put_u32(skb,
3244 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303245 pData->ieLength) ||
3246 nla_put_u8(skb,
3247 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3248 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303249 {
3250 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3251 goto nla_put_failure;
3252 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303253
3254 if (pData->ieLength) {
3255 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3256 pData->ieLength,
3257 pData->ie))
3258 {
3259 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3260 goto nla_put_failure;
3261 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303262 }
3263
3264 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303265 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303266 return;
3267
3268nla_put_failure:
3269 kfree_skb(skb);
3270 return;
3271}
3272
3273static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3274 void *pMsg)
3275{
3276 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3277 struct sk_buff *skb = NULL;
3278 tpSirEXTScanResultsAvailableIndParams pData =
3279 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3280
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303281 ENTER();
3282
3283 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303284 hddLog(LOGE,
3285 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303286 return;
3287 }
3288 if (!pMsg)
3289 {
3290 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303291 return;
3292 }
3293
3294 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303295#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3296 NULL,
3297#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303298 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3299 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3300 GFP_KERNEL);
3301
3302 if (!skb) {
3303 hddLog(VOS_TRACE_LEVEL_ERROR,
3304 FL("cfg80211_vendor_event_alloc failed"));
3305 return;
3306 }
3307
Dino Mycle6fb96c12014-06-10 11:52:40 +05303308 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3309 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3310 pData->numResultsAvailable);
3311 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3312 pData->requestId) ||
3313 nla_put_u32(skb,
3314 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3315 pData->numResultsAvailable)) {
3316 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3317 goto nla_put_failure;
3318 }
3319
3320 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303321 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303322 return;
3323
3324nla_put_failure:
3325 kfree_skb(skb);
3326 return;
3327}
3328
3329static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3330{
3331 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3332 struct sk_buff *skb = NULL;
3333 tpSirEXTScanProgressIndParams pData =
3334 (tpSirEXTScanProgressIndParams) pMsg;
3335
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303336 ENTER();
3337
3338 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303339 hddLog(LOGE,
3340 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303341 return;
3342 }
3343 if (!pMsg)
3344 {
3345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303346 return;
3347 }
3348
3349 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303350#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3351 NULL,
3352#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303353 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3354 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3355 GFP_KERNEL);
3356
3357 if (!skb) {
3358 hddLog(VOS_TRACE_LEVEL_ERROR,
3359 FL("cfg80211_vendor_event_alloc failed"));
3360 return;
3361 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303362 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303363 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3364 pData->extScanEventType);
3365 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3366 pData->status);
3367
3368 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3369 pData->extScanEventType) ||
3370 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303371 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3372 pData->requestId) ||
3373 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303374 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3375 pData->status)) {
3376 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3377 goto nla_put_failure;
3378 }
3379
3380 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303381 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303382 return;
3383
3384nla_put_failure:
3385 kfree_skb(skb);
3386 return;
3387}
3388
3389void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3390 void *pMsg)
3391{
3392 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3393
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303394 ENTER();
3395
Dino Mycle6fb96c12014-06-10 11:52:40 +05303396 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303397 return;
3398 }
3399
3400 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3401
3402
3403 switch(evType) {
3404 case SIR_HAL_EXTSCAN_START_RSP:
3405 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3406 break;
3407
3408 case SIR_HAL_EXTSCAN_STOP_RSP:
3409 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3410 break;
3411 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3412 /* There is no need to send this response to upper layer
3413 Just log the message */
3414 hddLog(VOS_TRACE_LEVEL_INFO,
3415 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3416 break;
3417 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3418 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3419 break;
3420
3421 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3422 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3423 break;
3424
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303425 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3426 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3427 break;
3428
3429 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3430 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3431 break;
3432
Dino Mycle6fb96c12014-06-10 11:52:40 +05303433 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303434 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303435 break;
3436 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3437 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3438 break;
3439 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3440 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3441 break;
3442 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3443 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3444 break;
3445 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3446 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3447 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303448 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3449 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3450 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303451 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3452 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3453 break;
3454 default:
3455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3456 break;
3457 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303458 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303459}
3460
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303461static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3462 struct wireless_dev *wdev,
3463 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303464{
Dino Myclee8843b32014-07-04 14:21:45 +05303465 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303466 struct net_device *dev = wdev->netdev;
3467 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3468 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3469 struct nlattr
3470 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3471 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303472 struct hdd_ext_scan_context *context;
3473 unsigned long rc;
3474 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303475
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303476 ENTER();
3477
Dino Mycle6fb96c12014-06-10 11:52:40 +05303478 status = wlan_hdd_validate_context(pHddCtx);
3479 if (0 != status)
3480 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303481 return -EINVAL;
3482 }
Dino Myclee8843b32014-07-04 14:21:45 +05303483 /* check the EXTScan Capability */
3484 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303485 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3486 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303487 {
3488 hddLog(VOS_TRACE_LEVEL_ERROR,
3489 FL("EXTScan not enabled/supported by Firmware"));
3490 return -EINVAL;
3491 }
3492
Dino Mycle6fb96c12014-06-10 11:52:40 +05303493 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3494 data, dataLen,
3495 wlan_hdd_extscan_config_policy)) {
3496 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3497 return -EINVAL;
3498 }
3499
3500 /* Parse and fetch request Id */
3501 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3502 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3503 return -EINVAL;
3504 }
3505
Dino Myclee8843b32014-07-04 14:21:45 +05303506 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303507 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303508 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303509
Dino Myclee8843b32014-07-04 14:21:45 +05303510 reqMsg.sessionId = pAdapter->sessionId;
3511 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303512
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303513 vos_spin_lock_acquire(&hdd_context_lock);
3514 context = &pHddCtx->ext_scan_context;
3515 context->request_id = reqMsg.requestId;
3516 INIT_COMPLETION(context->response_event);
3517 vos_spin_lock_release(&hdd_context_lock);
3518
Dino Myclee8843b32014-07-04 14:21:45 +05303519 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303520 if (!HAL_STATUS_SUCCESS(status)) {
3521 hddLog(VOS_TRACE_LEVEL_ERROR,
3522 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303523 return -EINVAL;
3524 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303525
3526 rc = wait_for_completion_timeout(&context->response_event,
3527 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3528 if (!rc) {
3529 hddLog(LOGE, FL("Target response timed out"));
3530 return -ETIMEDOUT;
3531 }
3532
3533 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3534 if (ret)
3535 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3536
3537 return ret;
3538
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303539 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303540 return 0;
3541}
3542
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303543static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3544 struct wireless_dev *wdev,
3545 const void *data, int dataLen)
3546{
3547 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303548
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303549 vos_ssr_protect(__func__);
3550 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3551 vos_ssr_unprotect(__func__);
3552
3553 return ret;
3554}
3555
3556static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3557 struct wireless_dev *wdev,
3558 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303559{
Dino Myclee8843b32014-07-04 14:21:45 +05303560 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303561 struct net_device *dev = wdev->netdev;
3562 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3563 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3564 struct nlattr
3565 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3566 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303567 struct hdd_ext_scan_context *context;
3568 unsigned long rc;
3569 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303570
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303571 ENTER();
3572
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303573 if (VOS_FTM_MODE == hdd_get_conparam()) {
3574 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3575 return -EINVAL;
3576 }
3577
Dino Mycle6fb96c12014-06-10 11:52:40 +05303578 status = wlan_hdd_validate_context(pHddCtx);
3579 if (0 != status)
3580 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581 return -EINVAL;
3582 }
Dino Myclee8843b32014-07-04 14:21:45 +05303583 /* check the EXTScan Capability */
3584 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303585 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3586 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303587 {
3588 hddLog(VOS_TRACE_LEVEL_ERROR,
3589 FL("EXTScan not enabled/supported by Firmware"));
3590 return -EINVAL;
3591 }
3592
Dino Mycle6fb96c12014-06-10 11:52:40 +05303593 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3594 data, dataLen,
3595 wlan_hdd_extscan_config_policy)) {
3596 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3597 return -EINVAL;
3598 }
3599 /* Parse and fetch request Id */
3600 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3602 return -EINVAL;
3603 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303604
Dino Myclee8843b32014-07-04 14:21:45 +05303605 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303606 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3607
Dino Myclee8843b32014-07-04 14:21:45 +05303608 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303609
Dino Myclee8843b32014-07-04 14:21:45 +05303610 reqMsg.sessionId = pAdapter->sessionId;
3611 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303612
3613 /* Parse and fetch flush parameter */
3614 if (!tb
3615 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3616 {
3617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3618 goto failed;
3619 }
Dino Myclee8843b32014-07-04 14:21:45 +05303620 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303621 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3622
Dino Myclee8843b32014-07-04 14:21:45 +05303623 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303624
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303625 spin_lock(&hdd_context_lock);
3626 context = &pHddCtx->ext_scan_context;
3627 context->request_id = reqMsg.requestId;
3628 context->ignore_cached_results = false;
3629 INIT_COMPLETION(context->response_event);
3630 spin_unlock(&hdd_context_lock);
3631
Dino Myclee8843b32014-07-04 14:21:45 +05303632 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303633 if (!HAL_STATUS_SUCCESS(status)) {
3634 hddLog(VOS_TRACE_LEVEL_ERROR,
3635 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303636 return -EINVAL;
3637 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303638
3639 rc = wait_for_completion_timeout(&context->response_event,
3640 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3641 if (!rc) {
3642 hddLog(LOGE, FL("Target response timed out"));
3643 retval = -ETIMEDOUT;
3644 spin_lock(&hdd_context_lock);
3645 context->ignore_cached_results = true;
3646 spin_unlock(&hdd_context_lock);
3647 } else {
3648 spin_lock(&hdd_context_lock);
3649 retval = context->response_status;
3650 spin_unlock(&hdd_context_lock);
3651 }
3652
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303653 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303654 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303655
3656failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303657 return -EINVAL;
3658}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303659static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3660 struct wireless_dev *wdev,
3661 const void *data, int dataLen)
3662{
3663 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303664
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303665 vos_ssr_protect(__func__);
3666 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3667 vos_ssr_unprotect(__func__);
3668
3669 return ret;
3670}
3671
3672static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303673 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303674 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303675{
3676 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3677 struct net_device *dev = wdev->netdev;
3678 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3679 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3680 struct nlattr
3681 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3682 struct nlattr
3683 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3684 struct nlattr *apTh;
3685 eHalStatus status;
3686 tANI_U8 i = 0;
3687 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303688 struct hdd_ext_scan_context *context;
3689 tANI_U32 request_id;
3690 unsigned long rc;
3691 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303693 ENTER();
3694
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303695 if (VOS_FTM_MODE == hdd_get_conparam()) {
3696 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3697 return -EINVAL;
3698 }
3699
Dino Mycle6fb96c12014-06-10 11:52:40 +05303700 status = wlan_hdd_validate_context(pHddCtx);
3701 if (0 != status)
3702 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303703 return -EINVAL;
3704 }
Dino Myclee8843b32014-07-04 14:21:45 +05303705 /* check the EXTScan Capability */
3706 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303707 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3708 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303709 {
3710 hddLog(VOS_TRACE_LEVEL_ERROR,
3711 FL("EXTScan not enabled/supported by Firmware"));
3712 return -EINVAL;
3713 }
3714
Dino Mycle6fb96c12014-06-10 11:52:40 +05303715 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3716 data, dataLen,
3717 wlan_hdd_extscan_config_policy)) {
3718 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3719 return -EINVAL;
3720 }
3721
3722 /* Parse and fetch request Id */
3723 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3724 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3725 return -EINVAL;
3726 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303727 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3728 vos_mem_malloc(sizeof(*pReqMsg));
3729 if (!pReqMsg) {
3730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3731 return -ENOMEM;
3732 }
3733
Dino Myclee8843b32014-07-04 14:21:45 +05303734
Dino Mycle6fb96c12014-06-10 11:52:40 +05303735 pReqMsg->requestId = nla_get_u32(
3736 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3737 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3738
3739 /* Parse and fetch number of APs */
3740 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3742 goto fail;
3743 }
3744
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303745 /* Parse and fetch lost ap sample size */
3746 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3747 hddLog(LOGE, FL("attr lost ap sample size failed"));
3748 goto fail;
3749 }
3750
3751 pReqMsg->lostBssidSampleSize = nla_get_u32(
3752 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3753 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3754
Dino Mycle6fb96c12014-06-10 11:52:40 +05303755 pReqMsg->sessionId = pAdapter->sessionId;
3756 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3757
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303758 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303759 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303760 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303761
3762 nla_for_each_nested(apTh,
3763 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3764 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3765 nla_data(apTh), nla_len(apTh),
3766 NULL)) {
3767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3768 goto fail;
3769 }
3770
3771 /* Parse and fetch MAC address */
3772 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3773 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3774 goto fail;
3775 }
3776 memcpy(pReqMsg->ap[i].bssid, nla_data(
3777 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3778 sizeof(tSirMacAddr));
3779 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3780
3781 /* Parse and fetch low RSSI */
3782 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3784 goto fail;
3785 }
3786 pReqMsg->ap[i].low = nla_get_s32(
3787 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3788 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3789
3790 /* Parse and fetch high RSSI */
3791 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3793 goto fail;
3794 }
3795 pReqMsg->ap[i].high = nla_get_s32(
3796 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3797 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3798 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303799 i++;
3800 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303801
3802 context = &pHddCtx->ext_scan_context;
3803 spin_lock(&hdd_context_lock);
3804 INIT_COMPLETION(context->response_event);
3805 context->request_id = request_id = pReqMsg->requestId;
3806 spin_unlock(&hdd_context_lock);
3807
Dino Mycle6fb96c12014-06-10 11:52:40 +05303808 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3809 if (!HAL_STATUS_SUCCESS(status)) {
3810 hddLog(VOS_TRACE_LEVEL_ERROR,
3811 FL("sme_SetBssHotlist failed(err=%d)"), status);
3812 vos_mem_free(pReqMsg);
3813 return -EINVAL;
3814 }
3815
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303816 /* request was sent -- wait for the response */
3817 rc = wait_for_completion_timeout(&context->response_event,
3818 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3819
3820 if (!rc) {
3821 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3822 retval = -ETIMEDOUT;
3823 } else {
3824 spin_lock(&hdd_context_lock);
3825 if (context->request_id == request_id)
3826 retval = context->response_status;
3827 else
3828 retval = -EINVAL;
3829 spin_unlock(&hdd_context_lock);
3830 }
3831
Dino Myclee8843b32014-07-04 14:21:45 +05303832 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303833 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303834 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303835
3836fail:
3837 vos_mem_free(pReqMsg);
3838 return -EINVAL;
3839}
3840
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303841static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3842 struct wireless_dev *wdev,
3843 const void *data, int dataLen)
3844{
3845 int ret = 0;
3846
3847 vos_ssr_protect(__func__);
3848 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3849 dataLen);
3850 vos_ssr_unprotect(__func__);
3851
3852 return ret;
3853}
3854
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303855/*
3856 * define short names for the global vendor params
3857 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3858 */
3859#define PARAM_MAX \
3860QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3861#define PARAM_REQUEST_ID \
3862QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3863#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3864QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3865#define PARAMS_NUM_SSID \
3866QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3867#define THRESHOLD_PARAM \
3868QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3869#define PARAM_SSID \
3870QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3871#define PARAM_BAND \
3872QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3873#define PARAM_RSSI_LOW \
3874QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3875#define PARAM_RSSI_HIGH \
3876QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3877
3878/**
3879 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3880 * @wiphy: Pointer to wireless phy
3881 * @wdev: Pointer to wireless device
3882 * @data: Pointer to data
3883 * @data_len: Data length
3884 *
3885 * Return: 0 on success, negative errno on failure
3886 */
3887static int
3888__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3889 struct wireless_dev *wdev,
3890 const void *data,
3891 int data_len)
3892{
3893 tSirEXTScanSetSsidHotListReqParams *request;
3894 struct net_device *dev = wdev->netdev;
3895 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3896 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3897 struct nlattr *tb[PARAM_MAX + 1];
3898 struct nlattr *tb2[PARAM_MAX + 1];
3899 struct nlattr *ssids;
3900 struct hdd_ext_scan_context *context;
3901 uint32_t request_id;
3902 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3903 int ssid_len;
3904 eHalStatus status;
3905 int i, rem, retval;
3906 unsigned long rc;
3907
3908 ENTER();
3909
3910 if (VOS_FTM_MODE == hdd_get_conparam()) {
3911 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3912 return -EINVAL;
3913 }
3914
3915 retval = wlan_hdd_validate_context(hdd_ctx);
3916 if (0 != retval) {
3917 hddLog(LOGE, FL("HDD context is not valid"));
3918 return -EINVAL;
3919 }
3920
3921 /* check the EXTScan Capability */
3922 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303923 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3924 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303925 {
3926 hddLog(VOS_TRACE_LEVEL_ERROR,
3927 FL("EXTScan not enabled/supported by Firmware"));
3928 return -EINVAL;
3929 }
3930
3931 if (nla_parse(tb, PARAM_MAX,
3932 data, data_len,
3933 wlan_hdd_extscan_config_policy)) {
3934 hddLog(LOGE, FL("Invalid ATTR"));
3935 return -EINVAL;
3936 }
3937
3938 request = vos_mem_malloc(sizeof(*request));
3939 if (!request) {
3940 hddLog(LOGE, FL("vos_mem_malloc failed"));
3941 return -ENOMEM;
3942 }
3943
3944 /* Parse and fetch request Id */
3945 if (!tb[PARAM_REQUEST_ID]) {
3946 hddLog(LOGE, FL("attr request id failed"));
3947 goto fail;
3948 }
3949
3950 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3951 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3952
3953 /* Parse and fetch lost SSID sample size */
3954 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3955 hddLog(LOGE, FL("attr number of Ssid failed"));
3956 goto fail;
3957 }
3958 request->lost_ssid_sample_size =
3959 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3960 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3961 request->lost_ssid_sample_size);
3962
3963 /* Parse and fetch number of hotlist SSID */
3964 if (!tb[PARAMS_NUM_SSID]) {
3965 hddLog(LOGE, FL("attr number of Ssid failed"));
3966 goto fail;
3967 }
3968 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3969 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3970
3971 request->session_id = adapter->sessionId;
3972 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3973
3974 i = 0;
3975 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3976 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3977 hddLog(LOGE,
3978 FL("Too Many SSIDs, %d exceeds %d"),
3979 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3980 break;
3981 }
3982 if (nla_parse(tb2, PARAM_MAX,
3983 nla_data(ssids), nla_len(ssids),
3984 wlan_hdd_extscan_config_policy)) {
3985 hddLog(LOGE, FL("nla_parse failed"));
3986 goto fail;
3987 }
3988
3989 /* Parse and fetch SSID */
3990 if (!tb2[PARAM_SSID]) {
3991 hddLog(LOGE, FL("attr ssid failed"));
3992 goto fail;
3993 }
3994 nla_memcpy(ssid_string,
3995 tb2[PARAM_SSID],
3996 sizeof(ssid_string));
3997 hddLog(LOG1, FL("SSID %s"),
3998 ssid_string);
3999 ssid_len = strlen(ssid_string);
4000 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
4001 request->ssid[i].ssid.length = ssid_len;
4002 request->ssid[i].ssid.ssId[ssid_len] = '\0';
4003 hddLog(LOG1, FL("After copying SSID %s"),
4004 request->ssid[i].ssid.ssId);
4005 hddLog(LOG1, FL("After copying length: %d"),
4006 ssid_len);
4007
4008 /* Parse and fetch low RSSI */
4009 if (!tb2[PARAM_BAND]) {
4010 hddLog(LOGE, FL("attr band failed"));
4011 goto fail;
4012 }
4013 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
4014 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
4015
4016 /* Parse and fetch low RSSI */
4017 if (!tb2[PARAM_RSSI_LOW]) {
4018 hddLog(LOGE, FL("attr low RSSI failed"));
4019 goto fail;
4020 }
4021 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4022 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4023
4024 /* Parse and fetch high RSSI */
4025 if (!tb2[PARAM_RSSI_HIGH]) {
4026 hddLog(LOGE, FL("attr high RSSI failed"));
4027 goto fail;
4028 }
4029 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4030 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4031 i++;
4032 }
4033
4034 context = &hdd_ctx->ext_scan_context;
4035 spin_lock(&hdd_context_lock);
4036 INIT_COMPLETION(context->response_event);
4037 context->request_id = request_id = request->request_id;
4038 spin_unlock(&hdd_context_lock);
4039
4040 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4041 if (!HAL_STATUS_SUCCESS(status)) {
4042 hddLog(LOGE,
4043 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4044 goto fail;
4045 }
4046
4047 vos_mem_free(request);
4048
4049 /* request was sent -- wait for the response */
4050 rc = wait_for_completion_timeout(&context->response_event,
4051 msecs_to_jiffies
4052 (WLAN_WAIT_TIME_EXTSCAN));
4053 if (!rc) {
4054 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4055 retval = -ETIMEDOUT;
4056 } else {
4057 spin_lock(&hdd_context_lock);
4058 if (context->request_id == request_id)
4059 retval = context->response_status;
4060 else
4061 retval = -EINVAL;
4062 spin_unlock(&hdd_context_lock);
4063 }
4064
4065 return retval;
4066
4067fail:
4068 vos_mem_free(request);
4069 return -EINVAL;
4070}
4071
4072/*
4073 * done with short names for the global vendor params
4074 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4075 */
4076#undef PARAM_MAX
4077#undef PARAM_REQUEST_ID
4078#undef PARAMS_NUM_SSID
4079#undef THRESHOLD_PARAM
4080#undef PARAM_SSID
4081#undef PARAM_BAND
4082#undef PARAM_RSSI_LOW
4083#undef PARAM_RSSI_HIGH
4084
4085static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4086 struct wireless_dev *wdev,
4087 const void *data, int dataLen)
4088{
4089 int ret = 0;
4090
4091 vos_ssr_protect(__func__);
4092 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4093 dataLen);
4094 vos_ssr_unprotect(__func__);
4095
4096 return ret;
4097}
4098
4099static int
4100__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4101 struct wireless_dev *wdev,
4102 const void *data,
4103 int data_len)
4104{
4105 tSirEXTScanResetSsidHotlistReqParams request;
4106 struct net_device *dev = wdev->netdev;
4107 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4108 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4109 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4110 struct hdd_ext_scan_context *context;
4111 uint32_t request_id;
4112 eHalStatus status;
4113 int retval;
4114 unsigned long rc;
4115
4116 ENTER();
4117
4118 if (VOS_FTM_MODE == hdd_get_conparam()) {
4119 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4120 return -EINVAL;
4121 }
4122
4123 retval = wlan_hdd_validate_context(hdd_ctx);
4124 if (0 != retval) {
4125 hddLog(LOGE, FL("HDD context is not valid"));
4126 return -EINVAL;
4127 }
4128
4129 /* check the EXTScan Capability */
4130 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304131 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4132 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304133 {
4134 hddLog(LOGE,
4135 FL("EXTScan not enabled/supported by Firmware"));
4136 return -EINVAL;
4137 }
4138
4139 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4140 data, data_len,
4141 wlan_hdd_extscan_config_policy)) {
4142 hddLog(LOGE, FL("Invalid ATTR"));
4143 return -EINVAL;
4144 }
4145
4146 /* Parse and fetch request Id */
4147 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4148 hddLog(LOGE, FL("attr request id failed"));
4149 return -EINVAL;
4150 }
4151
4152 request.requestId = nla_get_u32(
4153 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4154 request.sessionId = adapter->sessionId;
4155 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4156 request.sessionId);
4157
4158 context = &hdd_ctx->ext_scan_context;
4159 spin_lock(&hdd_context_lock);
4160 INIT_COMPLETION(context->response_event);
4161 context->request_id = request_id = request.requestId;
4162 spin_unlock(&hdd_context_lock);
4163
4164 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4165 if (!HAL_STATUS_SUCCESS(status)) {
4166 hddLog(LOGE,
4167 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4168 return -EINVAL;
4169 }
4170
4171 /* request was sent -- wait for the response */
4172 rc = wait_for_completion_timeout(&context->response_event,
4173 msecs_to_jiffies
4174 (WLAN_WAIT_TIME_EXTSCAN));
4175 if (!rc) {
4176 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4177 retval = -ETIMEDOUT;
4178 } else {
4179 spin_lock(&hdd_context_lock);
4180 if (context->request_id == request_id)
4181 retval = context->response_status;
4182 else
4183 retval = -EINVAL;
4184 spin_unlock(&hdd_context_lock);
4185 }
4186
4187 return retval;
4188}
4189
4190static int
4191wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4192 struct wireless_dev *wdev,
4193 const void *data,
4194 int data_len)
4195{
4196 int ret;
4197
4198 vos_ssr_protect(__func__);
4199 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4200 data, data_len);
4201 vos_ssr_unprotect(__func__);
4202
4203 return ret;
4204}
4205
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304206static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304207 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304208 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304209{
4210 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4211 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4212 tANI_U8 numChannels = 0;
4213 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304214 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304215 tWifiBand wifiBand;
4216 eHalStatus status;
4217 struct sk_buff *replySkb;
4218 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304219 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304220
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304221 ENTER();
4222
Dino Mycle6fb96c12014-06-10 11:52:40 +05304223 status = wlan_hdd_validate_context(pHddCtx);
4224 if (0 != status)
4225 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304226 return -EINVAL;
4227 }
Dino Myclee8843b32014-07-04 14:21:45 +05304228
Dino Mycle6fb96c12014-06-10 11:52:40 +05304229 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4230 data, dataLen,
4231 wlan_hdd_extscan_config_policy)) {
4232 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4233 return -EINVAL;
4234 }
4235
4236 /* Parse and fetch request Id */
4237 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4239 return -EINVAL;
4240 }
4241 requestId = nla_get_u32(
4242 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4243 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4244
4245 /* Parse and fetch wifi band */
4246 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4247 {
4248 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4249 return -EINVAL;
4250 }
4251 wifiBand = nla_get_u32(
4252 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4253 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4254
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304255 /* Parse and fetch max channels */
4256 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4257 {
4258 hddLog(LOGE, FL("attr max channels failed"));
4259 return -EINVAL;
4260 }
4261 maxChannels = nla_get_u32(
4262 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4263 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4264
Dino Mycle6fb96c12014-06-10 11:52:40 +05304265 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4266 wifiBand, ChannelList,
4267 &numChannels);
4268 if (eHAL_STATUS_SUCCESS != status) {
4269 hddLog(VOS_TRACE_LEVEL_ERROR,
4270 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4271 return -EINVAL;
4272 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304273
4274 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304275 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304276
Dino Mycle6fb96c12014-06-10 11:52:40 +05304277 for (i = 0; i < numChannels; i++)
4278 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4279
4280 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4281 sizeof(u32) * numChannels +
4282 NLMSG_HDRLEN);
4283
4284 if (!replySkb) {
4285 hddLog(VOS_TRACE_LEVEL_ERROR,
4286 FL("valid channels: buffer alloc fail"));
4287 return -EINVAL;
4288 }
4289 if (nla_put_u32(replySkb,
4290 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4291 numChannels) ||
4292 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4293 sizeof(u32) * numChannels, ChannelList)) {
4294
4295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4296 kfree_skb(replySkb);
4297 return -EINVAL;
4298 }
4299
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304300 ret = cfg80211_vendor_cmd_reply(replySkb);
4301
4302 EXIT();
4303 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304304}
4305
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304306static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4307 struct wireless_dev *wdev,
4308 const void *data, int dataLen)
4309{
4310 int ret = 0;
4311
4312 vos_ssr_protect(__func__);
4313 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4314 dataLen);
4315 vos_ssr_unprotect(__func__);
4316
4317 return ret;
4318}
4319
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304320static int hdd_extscan_start_fill_bucket_channel_spec(
4321 hdd_context_t *pHddCtx,
4322 tpSirEXTScanStartReqParams pReqMsg,
4323 struct nlattr **tb)
4324{
4325 struct nlattr *bucket[
4326 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4327 struct nlattr *channel[
4328 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4329 struct nlattr *buckets;
4330 struct nlattr *channels;
4331 int rem1, rem2;
4332 eHalStatus status;
4333 tANI_U8 bktIndex, j, numChannels;
4334 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4335 tANI_U32 passive_max_chn_time, active_max_chn_time;
4336
4337 bktIndex = 0;
4338
4339 nla_for_each_nested(buckets,
4340 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4341 if (nla_parse(bucket,
4342 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4343 nla_data(buckets), nla_len(buckets), NULL)) {
4344 hddLog(LOGE, FL("nla_parse failed"));
4345 return -EINVAL;
4346 }
4347
4348 /* Parse and fetch bucket spec */
4349 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4350 hddLog(LOGE, FL("attr bucket index failed"));
4351 return -EINVAL;
4352 }
4353 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4354 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4355 hddLog(LOG1, FL("Bucket spec Index %d"),
4356 pReqMsg->buckets[bktIndex].bucket);
4357
4358 /* Parse and fetch wifi band */
4359 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4360 hddLog(LOGE, FL("attr wifi band failed"));
4361 return -EINVAL;
4362 }
4363 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4364 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4365 hddLog(LOG1, FL("Wifi band %d"),
4366 pReqMsg->buckets[bktIndex].band);
4367
4368 /* Parse and fetch period */
4369 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4370 hddLog(LOGE, FL("attr period failed"));
4371 return -EINVAL;
4372 }
4373 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4374 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4375 hddLog(LOG1, FL("period %d"),
4376 pReqMsg->buckets[bktIndex].period);
4377
4378 /* Parse and fetch report events */
4379 if (!bucket[
4380 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4381 hddLog(LOGE, FL("attr report events failed"));
4382 return -EINVAL;
4383 }
4384 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4385 bucket[
4386 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4387 hddLog(LOG1, FL("report events %d"),
4388 pReqMsg->buckets[bktIndex].reportEvents);
4389
4390 /* Parse and fetch max period */
4391 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4392 hddLog(LOGE, FL("attr max period failed"));
4393 return -EINVAL;
4394 }
4395 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4396 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4397 hddLog(LOG1, FL("max period %u"),
4398 pReqMsg->buckets[bktIndex].max_period);
4399
4400 /* Parse and fetch exponent */
4401 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4402 hddLog(LOGE, FL("attr exponent failed"));
4403 return -EINVAL;
4404 }
4405 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4406 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4407 hddLog(LOG1, FL("exponent %u"),
4408 pReqMsg->buckets[bktIndex].exponent);
4409
4410 /* Parse and fetch step count */
4411 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4412 hddLog(LOGE, FL("attr step count failed"));
4413 return -EINVAL;
4414 }
4415 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4416 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4417 hddLog(LOG1, FL("Step count %u"),
4418 pReqMsg->buckets[bktIndex].step_count);
4419
4420 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4421 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4422
4423 /* Framework shall pass the channel list if the input WiFi band is
4424 * WIFI_BAND_UNSPECIFIED.
4425 * If the input WiFi band is specified (any value other than
4426 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4427 */
4428 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4429 numChannels = 0;
4430 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4431 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4432 pReqMsg->buckets[bktIndex].band,
4433 chanList, &numChannels);
4434 if (!HAL_STATUS_SUCCESS(status)) {
4435 hddLog(LOGE,
4436 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4437 status);
4438 return -EINVAL;
4439 }
4440
4441 pReqMsg->buckets[bktIndex].numChannels =
4442 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4443 hddLog(LOG1, FL("Num channels %d"),
4444 pReqMsg->buckets[bktIndex].numChannels);
4445
4446 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4447 j++) {
4448 pReqMsg->buckets[bktIndex].channels[j].channel =
4449 chanList[j];
4450 pReqMsg->buckets[bktIndex].channels[j].
4451 chnlClass = 0;
4452 if (CSR_IS_CHANNEL_DFS(
4453 vos_freq_to_chan(chanList[j]))) {
4454 pReqMsg->buckets[bktIndex].channels[j].
4455 passive = 1;
4456 pReqMsg->buckets[bktIndex].channels[j].
4457 dwellTimeMs = passive_max_chn_time;
4458 } else {
4459 pReqMsg->buckets[bktIndex].channels[j].
4460 passive = 0;
4461 pReqMsg->buckets[bktIndex].channels[j].
4462 dwellTimeMs = active_max_chn_time;
4463 }
4464
4465 hddLog(LOG1,
4466 "Channel %u Passive %u Dwell time %u ms",
4467 pReqMsg->buckets[bktIndex].channels[j].channel,
4468 pReqMsg->buckets[bktIndex].channels[j].passive,
4469 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4470 }
4471
4472 bktIndex++;
4473 continue;
4474 }
4475
4476 /* Parse and fetch number of channels */
4477 if (!bucket[
4478 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4479 hddLog(LOGE, FL("attr num channels failed"));
4480 return -EINVAL;
4481 }
4482
4483 pReqMsg->buckets[bktIndex].numChannels =
4484 nla_get_u32(bucket[
4485 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4486 hddLog(LOG1, FL("num channels %d"),
4487 pReqMsg->buckets[bktIndex].numChannels);
4488
4489 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4490 hddLog(LOGE, FL("attr channel spec failed"));
4491 return -EINVAL;
4492 }
4493
4494 j = 0;
4495 nla_for_each_nested(channels,
4496 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4497 if (nla_parse(channel,
4498 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4499 nla_data(channels), nla_len(channels),
4500 wlan_hdd_extscan_config_policy)) {
4501 hddLog(LOGE, FL("nla_parse failed"));
4502 return -EINVAL;
4503 }
4504
4505 /* Parse and fetch channel */
4506 if (!channel[
4507 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4508 hddLog(LOGE, FL("attr channel failed"));
4509 return -EINVAL;
4510 }
4511 pReqMsg->buckets[bktIndex].channels[j].channel =
4512 nla_get_u32(channel[
4513 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4514 hddLog(LOG1, FL("channel %u"),
4515 pReqMsg->buckets[bktIndex].channels[j].channel);
4516
4517 /* Parse and fetch dwell time */
4518 if (!channel[
4519 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4520 hddLog(LOGE, FL("attr dwelltime failed"));
4521 return -EINVAL;
4522 }
4523 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4524 nla_get_u32(channel[
4525 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4526
4527 hddLog(LOG1, FL("Dwell time (%u ms)"),
4528 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4529
4530
4531 /* Parse and fetch channel spec passive */
4532 if (!channel[
4533 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4534 hddLog(LOGE,
4535 FL("attr channel spec passive failed"));
4536 return -EINVAL;
4537 }
4538 pReqMsg->buckets[bktIndex].channels[j].passive =
4539 nla_get_u8(channel[
4540 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4541 hddLog(LOG1, FL("Chnl spec passive %u"),
4542 pReqMsg->buckets[bktIndex].channels[j].passive);
4543
4544 j++;
4545 }
4546
4547 bktIndex++;
4548 }
4549
4550 return 0;
4551}
4552
4553
4554/*
4555 * define short names for the global vendor params
4556 * used by wlan_hdd_cfg80211_extscan_start()
4557 */
4558#define PARAM_MAX \
4559QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4560#define PARAM_REQUEST_ID \
4561QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4562#define PARAM_BASE_PERIOD \
4563QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4564#define PARAM_MAX_AP_PER_SCAN \
4565QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4566#define PARAM_RPT_THRHLD_PERCENT \
4567QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4568#define PARAM_RPT_THRHLD_NUM_SCANS \
4569QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4570#define PARAM_NUM_BUCKETS \
4571QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4572
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304573static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304574 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304575 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304576{
Dino Myclee8843b32014-07-04 14:21:45 +05304577 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304578 struct net_device *dev = wdev->netdev;
4579 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4580 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4581 struct nlattr *tb[PARAM_MAX + 1];
4582 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304583 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304584 tANI_U32 request_id;
4585 struct hdd_ext_scan_context *context;
4586 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304587
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304588 ENTER();
4589
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304590 if (VOS_FTM_MODE == hdd_get_conparam()) {
4591 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4592 return -EINVAL;
4593 }
4594
Dino Mycle6fb96c12014-06-10 11:52:40 +05304595 status = wlan_hdd_validate_context(pHddCtx);
4596 if (0 != status)
4597 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304598 return -EINVAL;
4599 }
Dino Myclee8843b32014-07-04 14:21:45 +05304600 /* check the EXTScan Capability */
4601 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304602 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4603 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304604 {
4605 hddLog(VOS_TRACE_LEVEL_ERROR,
4606 FL("EXTScan not enabled/supported by Firmware"));
4607 return -EINVAL;
4608 }
4609
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304610 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304611 data, dataLen,
4612 wlan_hdd_extscan_config_policy)) {
4613 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4614 return -EINVAL;
4615 }
4616
4617 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304618 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304619 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4620 return -EINVAL;
4621 }
4622
Dino Myclee8843b32014-07-04 14:21:45 +05304623 pReqMsg = (tpSirEXTScanStartReqParams)
4624 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304625 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304626 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4627 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304628 }
4629
4630 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304631 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304632 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4633
4634 pReqMsg->sessionId = pAdapter->sessionId;
4635 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4636
4637 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304638 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304639 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4640 goto fail;
4641 }
4642 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304643 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304644 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4645 pReqMsg->basePeriod);
4646
4647 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304648 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304649 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4650 goto fail;
4651 }
4652 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304653 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304654 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4655 pReqMsg->maxAPperScan);
4656
4657 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304658 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4660 goto fail;
4661 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304662 pReqMsg->reportThresholdPercent = nla_get_u8(
4663 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304664 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304665 pReqMsg->reportThresholdPercent);
4666
4667 /* Parse and fetch report threshold num scans */
4668 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4669 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4670 goto fail;
4671 }
4672 pReqMsg->reportThresholdNumScans = nla_get_u8(
4673 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4674 hddLog(LOG1, FL("Report Threshold num scans %d"),
4675 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304676
4677 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304678 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4680 goto fail;
4681 }
4682 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304683 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304684 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4685 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4686 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4687 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4688 }
4689 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4690 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304691
Dino Mycle6fb96c12014-06-10 11:52:40 +05304692 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4693 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4694 goto fail;
4695 }
4696
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304697 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304698
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304699 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4700 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304701
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304702 context = &pHddCtx->ext_scan_context;
4703 spin_lock(&hdd_context_lock);
4704 INIT_COMPLETION(context->response_event);
4705 context->request_id = request_id = pReqMsg->requestId;
4706 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304707
Dino Mycle6fb96c12014-06-10 11:52:40 +05304708 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4709 if (!HAL_STATUS_SUCCESS(status)) {
4710 hddLog(VOS_TRACE_LEVEL_ERROR,
4711 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304712 goto fail;
4713 }
4714
4715 /* request was sent -- wait for the response */
4716 rc = wait_for_completion_timeout(&context->response_event,
4717 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4718
4719 if (!rc) {
4720 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4721 retval = -ETIMEDOUT;
4722 } else {
4723 spin_lock(&hdd_context_lock);
4724 if (context->request_id == request_id)
4725 retval = context->response_status;
4726 else
4727 retval = -EINVAL;
4728 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304729 }
4730
Dino Myclee8843b32014-07-04 14:21:45 +05304731 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304732 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304733 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304734
4735fail:
4736 vos_mem_free(pReqMsg);
4737 return -EINVAL;
4738}
4739
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304740/*
4741 * done with short names for the global vendor params
4742 * used by wlan_hdd_cfg80211_extscan_start()
4743 */
4744#undef PARAM_MAX
4745#undef PARAM_REQUEST_ID
4746#undef PARAM_BASE_PERIOD
4747#undef PARAMS_MAX_AP_PER_SCAN
4748#undef PARAMS_RPT_THRHLD_PERCENT
4749#undef PARAMS_RPT_THRHLD_NUM_SCANS
4750#undef PARAMS_NUM_BUCKETS
4751
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304752static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4753 struct wireless_dev *wdev,
4754 const void *data, int dataLen)
4755{
4756 int ret = 0;
4757
4758 vos_ssr_protect(__func__);
4759 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4760 vos_ssr_unprotect(__func__);
4761
4762 return ret;
4763}
4764
4765static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304766 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304767 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304768{
Dino Myclee8843b32014-07-04 14:21:45 +05304769 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304770 struct net_device *dev = wdev->netdev;
4771 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4772 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4773 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4774 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304775 int retval;
4776 unsigned long rc;
4777 struct hdd_ext_scan_context *context;
4778 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304779
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304780 ENTER();
4781
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304782 if (VOS_FTM_MODE == hdd_get_conparam()) {
4783 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4784 return -EINVAL;
4785 }
4786
Dino Mycle6fb96c12014-06-10 11:52:40 +05304787 status = wlan_hdd_validate_context(pHddCtx);
4788 if (0 != status)
4789 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304790 return -EINVAL;
4791 }
Dino Myclee8843b32014-07-04 14:21:45 +05304792 /* check the EXTScan Capability */
4793 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304794 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4795 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304796 {
4797 hddLog(VOS_TRACE_LEVEL_ERROR,
4798 FL("EXTScan not enabled/supported by Firmware"));
4799 return -EINVAL;
4800 }
4801
Dino Mycle6fb96c12014-06-10 11:52:40 +05304802 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4803 data, dataLen,
4804 wlan_hdd_extscan_config_policy)) {
4805 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4806 return -EINVAL;
4807 }
4808
4809 /* Parse and fetch request Id */
4810 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4812 return -EINVAL;
4813 }
4814
Dino Myclee8843b32014-07-04 14:21:45 +05304815 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304816 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304817 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304818
Dino Myclee8843b32014-07-04 14:21:45 +05304819 reqMsg.sessionId = pAdapter->sessionId;
4820 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304821
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304822 context = &pHddCtx->ext_scan_context;
4823 spin_lock(&hdd_context_lock);
4824 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304825 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304826 spin_unlock(&hdd_context_lock);
4827
Dino Myclee8843b32014-07-04 14:21:45 +05304828 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304829 if (!HAL_STATUS_SUCCESS(status)) {
4830 hddLog(VOS_TRACE_LEVEL_ERROR,
4831 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304832 return -EINVAL;
4833 }
4834
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304835 /* request was sent -- wait for the response */
4836 rc = wait_for_completion_timeout(&context->response_event,
4837 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4838
4839 if (!rc) {
4840 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4841 retval = -ETIMEDOUT;
4842 } else {
4843 spin_lock(&hdd_context_lock);
4844 if (context->request_id == request_id)
4845 retval = context->response_status;
4846 else
4847 retval = -EINVAL;
4848 spin_unlock(&hdd_context_lock);
4849 }
4850
4851 return retval;
4852
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304853 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304854 return 0;
4855}
4856
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304857static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4858 struct wireless_dev *wdev,
4859 const void *data, int dataLen)
4860{
4861 int ret = 0;
4862
4863 vos_ssr_protect(__func__);
4864 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4865 vos_ssr_unprotect(__func__);
4866
4867 return ret;
4868}
4869
4870static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304871 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304872 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304873{
Dino Myclee8843b32014-07-04 14:21:45 +05304874 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304875 struct net_device *dev = wdev->netdev;
4876 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4877 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4878 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4879 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304880 struct hdd_ext_scan_context *context;
4881 tANI_U32 request_id;
4882 unsigned long rc;
4883 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304884
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304885 ENTER();
4886
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304887 if (VOS_FTM_MODE == hdd_get_conparam()) {
4888 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4889 return -EINVAL;
4890 }
4891
Dino Mycle6fb96c12014-06-10 11:52:40 +05304892 status = wlan_hdd_validate_context(pHddCtx);
4893 if (0 != status)
4894 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304895 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304896 return -EINVAL;
4897 }
Dino Myclee8843b32014-07-04 14:21:45 +05304898 /* check the EXTScan Capability */
4899 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304900 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4901 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304902 {
4903 hddLog(VOS_TRACE_LEVEL_ERROR,
4904 FL("EXTScan not enabled/supported by Firmware"));
4905 return -EINVAL;
4906 }
4907
Dino Mycle6fb96c12014-06-10 11:52:40 +05304908 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4909 data, dataLen,
4910 wlan_hdd_extscan_config_policy)) {
4911 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4912 return -EINVAL;
4913 }
4914
4915 /* Parse and fetch request Id */
4916 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4918 return -EINVAL;
4919 }
4920
Dino Myclee8843b32014-07-04 14:21:45 +05304921 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304922 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304923 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304924
Dino Myclee8843b32014-07-04 14:21:45 +05304925 reqMsg.sessionId = pAdapter->sessionId;
4926 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304927
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304928 context = &pHddCtx->ext_scan_context;
4929 spin_lock(&hdd_context_lock);
4930 INIT_COMPLETION(context->response_event);
4931 context->request_id = request_id = reqMsg.requestId;
4932 spin_unlock(&hdd_context_lock);
4933
Dino Myclee8843b32014-07-04 14:21:45 +05304934 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304935 if (!HAL_STATUS_SUCCESS(status)) {
4936 hddLog(VOS_TRACE_LEVEL_ERROR,
4937 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304938 return -EINVAL;
4939 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304940
4941 /* request was sent -- wait for the response */
4942 rc = wait_for_completion_timeout(&context->response_event,
4943 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4944 if (!rc) {
4945 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4946 retval = -ETIMEDOUT;
4947 } else {
4948 spin_lock(&hdd_context_lock);
4949 if (context->request_id == request_id)
4950 retval = context->response_status;
4951 else
4952 retval = -EINVAL;
4953 spin_unlock(&hdd_context_lock);
4954 }
4955
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304956 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304957 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304958}
4959
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304960static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4961 struct wireless_dev *wdev,
4962 const void *data, int dataLen)
4963{
4964 int ret = 0;
4965
4966 vos_ssr_protect(__func__);
4967 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4968 vos_ssr_unprotect(__func__);
4969
4970 return ret;
4971}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304972#endif /* WLAN_FEATURE_EXTSCAN */
4973
Atul Mittal115287b2014-07-08 13:26:33 +05304974/*EXT TDLS*/
4975static const struct nla_policy
4976wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4977{
4978 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4979 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4980 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4981 {.type = NLA_S32 },
4982 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4983 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4984
4985};
4986
4987static const struct nla_policy
4988wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4989{
4990 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4991
4992};
4993
4994static const struct nla_policy
4995wlan_hdd_tdls_config_state_change_policy[
4996 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4997{
4998 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4999 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5000 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305001 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5002 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5003 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305004
5005};
5006
5007static const struct nla_policy
5008wlan_hdd_tdls_config_get_status_policy[
5009 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5010{
5011 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5012 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5013 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305014 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5015 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5016 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305017
5018};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305019
5020static const struct nla_policy
5021wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5022{
5023 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5024};
5025
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305026static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305027 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305028 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305029 int data_len)
5030{
5031
5032 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5033 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5034
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305035 ENTER();
5036
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305037 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305038 return -EINVAL;
5039 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305040 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305041 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305042 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305043 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305044 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305045 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305046 return -ENOTSUPP;
5047 }
5048
5049 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5050 data, data_len, wlan_hdd_mac_config)) {
5051 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5052 return -EINVAL;
5053 }
5054
5055 /* Parse and fetch mac address */
5056 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5057 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5058 return -EINVAL;
5059 }
5060
5061 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5062 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5063 VOS_MAC_ADDR_LAST_3_BYTES);
5064
Siddharth Bhal76972212014-10-15 16:22:51 +05305065 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5066
5067 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305068 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5069 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305070 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5071 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5072 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5073 {
5074 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5075 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5076 VOS_MAC_ADDRESS_LEN);
5077 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305078 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305079
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305080 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5081 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305082
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305083 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305084 return 0;
5085}
5086
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305087static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5088 struct wireless_dev *wdev,
5089 const void *data,
5090 int data_len)
5091{
5092 int ret = 0;
5093
5094 vos_ssr_protect(__func__);
5095 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5096 vos_ssr_unprotect(__func__);
5097
5098 return ret;
5099}
5100
5101static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305102 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305103 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305104 int data_len)
5105{
5106 u8 peer[6] = {0};
5107 struct net_device *dev = wdev->netdev;
5108 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5109 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5110 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5111 eHalStatus ret;
5112 tANI_S32 state;
5113 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305114 tANI_S32 global_operating_class = 0;
5115 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305116 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305117 int retVal;
5118
5119 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305120
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305121 if (!pAdapter) {
5122 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5123 return -EINVAL;
5124 }
5125
Atul Mittal115287b2014-07-08 13:26:33 +05305126 ret = wlan_hdd_validate_context(pHddCtx);
5127 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305128 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305129 return -EINVAL;
5130 }
5131 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305132 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305133 return -ENOTSUPP;
5134 }
5135 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5136 data, data_len,
5137 wlan_hdd_tdls_config_get_status_policy)) {
5138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5139 return -EINVAL;
5140 }
5141
5142 /* Parse and fetch mac address */
5143 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5145 return -EINVAL;
5146 }
5147
5148 memcpy(peer, nla_data(
5149 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5150 sizeof(peer));
5151 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5152
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305153 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305154
Atul Mittal115287b2014-07-08 13:26:33 +05305155 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305156 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305157 NLMSG_HDRLEN);
5158
5159 if (!skb) {
5160 hddLog(VOS_TRACE_LEVEL_ERROR,
5161 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5162 return -EINVAL;
5163 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305164 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 +05305165 reason,
5166 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305167 global_operating_class,
5168 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305169 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305170 if (nla_put_s32(skb,
5171 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5172 state) ||
5173 nla_put_s32(skb,
5174 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5175 reason) ||
5176 nla_put_s32(skb,
5177 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5178 global_operating_class) ||
5179 nla_put_s32(skb,
5180 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5181 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305182
5183 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5184 goto nla_put_failure;
5185 }
5186
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305187 retVal = cfg80211_vendor_cmd_reply(skb);
5188 EXIT();
5189 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305190
5191nla_put_failure:
5192 kfree_skb(skb);
5193 return -EINVAL;
5194}
5195
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305196static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5197 struct wireless_dev *wdev,
5198 const void *data,
5199 int data_len)
5200{
5201 int ret = 0;
5202
5203 vos_ssr_protect(__func__);
5204 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5205 vos_ssr_unprotect(__func__);
5206
5207 return ret;
5208}
5209
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305210static int wlan_hdd_cfg80211_exttdls_callback(
5211#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5212 const tANI_U8* mac,
5213#else
5214 tANI_U8* mac,
5215#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305216 tANI_S32 state,
5217 tANI_S32 reason,
5218 void *ctx)
5219{
5220 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305221 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305222 tANI_S32 global_operating_class = 0;
5223 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305224 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305225
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305226 ENTER();
5227
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305228 if (!pAdapter) {
5229 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5230 return -EINVAL;
5231 }
5232
5233 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305234 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305235 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305236 return -EINVAL;
5237 }
5238
5239 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305240 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305241 return -ENOTSUPP;
5242 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305243 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5245 NULL,
5246#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305247 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5248 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5249 GFP_KERNEL);
5250
5251 if (!skb) {
5252 hddLog(VOS_TRACE_LEVEL_ERROR,
5253 FL("cfg80211_vendor_event_alloc failed"));
5254 return -EINVAL;
5255 }
5256 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305257 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5258 reason,
5259 state,
5260 global_operating_class,
5261 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305262 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5263 MAC_ADDR_ARRAY(mac));
5264
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305265 if (nla_put(skb,
5266 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5267 VOS_MAC_ADDR_SIZE, mac) ||
5268 nla_put_s32(skb,
5269 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5270 state) ||
5271 nla_put_s32(skb,
5272 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5273 reason) ||
5274 nla_put_s32(skb,
5275 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5276 channel) ||
5277 nla_put_s32(skb,
5278 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5279 global_operating_class)
5280 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305281 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5282 goto nla_put_failure;
5283 }
5284
5285 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305286 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305287 return (0);
5288
5289nla_put_failure:
5290 kfree_skb(skb);
5291 return -EINVAL;
5292}
5293
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305294static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305295 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305296 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305297 int data_len)
5298{
5299 u8 peer[6] = {0};
5300 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305301 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5302 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5303 eHalStatus status;
5304 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305305 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305306 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305307
5308 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305309
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305310 if (!dev) {
5311 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5312 return -EINVAL;
5313 }
5314
5315 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5316 if (!pAdapter) {
5317 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5318 return -EINVAL;
5319 }
5320
Atul Mittal115287b2014-07-08 13:26:33 +05305321 status = wlan_hdd_validate_context(pHddCtx);
5322 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305324 return -EINVAL;
5325 }
5326 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305327 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305328 return -ENOTSUPP;
5329 }
5330 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5331 data, data_len,
5332 wlan_hdd_tdls_config_enable_policy)) {
5333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5334 return -EINVAL;
5335 }
5336
5337 /* Parse and fetch mac address */
5338 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5339 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5340 return -EINVAL;
5341 }
5342
5343 memcpy(peer, nla_data(
5344 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5345 sizeof(peer));
5346 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5347
5348 /* Parse and fetch channel */
5349 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5350 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5351 return -EINVAL;
5352 }
5353 pReqMsg.channel = nla_get_s32(
5354 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5355 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5356
5357 /* Parse and fetch global operating class */
5358 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5359 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5360 return -EINVAL;
5361 }
5362 pReqMsg.global_operating_class = nla_get_s32(
5363 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5364 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5365 pReqMsg.global_operating_class);
5366
5367 /* Parse and fetch latency ms */
5368 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5369 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5370 return -EINVAL;
5371 }
5372 pReqMsg.max_latency_ms = nla_get_s32(
5373 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5374 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5375 pReqMsg.max_latency_ms);
5376
5377 /* Parse and fetch required bandwidth kbps */
5378 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5379 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5380 return -EINVAL;
5381 }
5382
5383 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5384 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5385 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5386 pReqMsg.min_bandwidth_kbps);
5387
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305388 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305389 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305390 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305391 wlan_hdd_cfg80211_exttdls_callback);
5392
5393 EXIT();
5394 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305395}
5396
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305397static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5398 struct wireless_dev *wdev,
5399 const void *data,
5400 int data_len)
5401{
5402 int ret = 0;
5403
5404 vos_ssr_protect(__func__);
5405 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5406 vos_ssr_unprotect(__func__);
5407
5408 return ret;
5409}
5410
5411static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305412 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305413 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305414 int data_len)
5415{
5416 u8 peer[6] = {0};
5417 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305418 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5419 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5420 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305421 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305422 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305423
5424 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305425
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305426 if (!dev) {
5427 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5428 return -EINVAL;
5429 }
5430
5431 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5432 if (!pAdapter) {
5433 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5434 return -EINVAL;
5435 }
5436
Atul Mittal115287b2014-07-08 13:26:33 +05305437 status = wlan_hdd_validate_context(pHddCtx);
5438 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305439 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305440 return -EINVAL;
5441 }
5442 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305443 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305444 return -ENOTSUPP;
5445 }
5446 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5447 data, data_len,
5448 wlan_hdd_tdls_config_disable_policy)) {
5449 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5450 return -EINVAL;
5451 }
5452 /* Parse and fetch mac address */
5453 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5454 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5455 return -EINVAL;
5456 }
5457
5458 memcpy(peer, nla_data(
5459 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5460 sizeof(peer));
5461 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5462
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305463 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5464
5465 EXIT();
5466 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305467}
5468
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305469static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5470 struct wireless_dev *wdev,
5471 const void *data,
5472 int data_len)
5473{
5474 int ret = 0;
5475
5476 vos_ssr_protect(__func__);
5477 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5478 vos_ssr_unprotect(__func__);
5479
5480 return ret;
5481}
5482
Dasari Srinivas7875a302014-09-26 17:50:57 +05305483static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305484__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305485 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305486 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305487{
5488 struct net_device *dev = wdev->netdev;
5489 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5490 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5491 struct sk_buff *skb = NULL;
5492 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305493 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305494
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305495 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305496
5497 ret = wlan_hdd_validate_context(pHddCtx);
5498 if (0 != ret)
5499 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305500 return ret;
5501 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305502 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5503 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5504 fset |= WIFI_FEATURE_INFRA;
5505 }
5506
5507 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5508 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5509 fset |= WIFI_FEATURE_INFRA_5G;
5510 }
5511
5512#ifdef WLAN_FEATURE_P2P
5513 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5514 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5515 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5516 fset |= WIFI_FEATURE_P2P;
5517 }
5518#endif
5519
5520 /* Soft-AP is supported currently by default */
5521 fset |= WIFI_FEATURE_SOFT_AP;
5522
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305523 /* HOTSPOT is a supplicant feature, enable it by default */
5524 fset |= WIFI_FEATURE_HOTSPOT;
5525
Dasari Srinivas7875a302014-09-26 17:50:57 +05305526#ifdef WLAN_FEATURE_EXTSCAN
5527 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305528 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5529 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5530 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305531 fset |= WIFI_FEATURE_EXTSCAN;
5532 }
5533#endif
5534
Dasari Srinivas7875a302014-09-26 17:50:57 +05305535 if (sme_IsFeatureSupportedByFW(NAN)) {
5536 hddLog(LOG1, FL("NAN is supported by firmware"));
5537 fset |= WIFI_FEATURE_NAN;
5538 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305539
5540 /* D2D RTT is not supported currently by default */
5541 if (sme_IsFeatureSupportedByFW(RTT)) {
5542 hddLog(LOG1, FL("RTT is supported by firmware"));
5543 fset |= WIFI_FEATURE_D2AP_RTT;
5544 }
5545
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305546 if (sme_IsFeatureSupportedByFW(RTT3)) {
5547 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5548 fset |= WIFI_FEATURE_RTT3;
5549 }
5550
Dasari Srinivas7875a302014-09-26 17:50:57 +05305551#ifdef FEATURE_WLAN_BATCH_SCAN
5552 if (fset & WIFI_FEATURE_EXTSCAN) {
5553 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5554 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5555 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5556 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5557 fset |= WIFI_FEATURE_BATCH_SCAN;
5558 }
5559#endif
5560
5561#ifdef FEATURE_WLAN_SCAN_PNO
5562 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5563 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5564 hddLog(LOG1, FL("PNO is supported by firmware"));
5565 fset |= WIFI_FEATURE_PNO;
5566 }
5567#endif
5568
5569 /* STA+STA is supported currently by default */
5570 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5571
5572#ifdef FEATURE_WLAN_TDLS
5573 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5574 sme_IsFeatureSupportedByFW(TDLS)) {
5575 hddLog(LOG1, FL("TDLS is supported by firmware"));
5576 fset |= WIFI_FEATURE_TDLS;
5577 }
5578
5579 /* TDLS_OFFCHANNEL is not supported currently by default */
5580#endif
5581
5582#ifdef WLAN_AP_STA_CONCURRENCY
5583 /* AP+STA concurrency is supported currently by default */
5584 fset |= WIFI_FEATURE_AP_STA;
5585#endif
5586
Mukul Sharma5add0532015-08-17 15:57:47 +05305587#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5588 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5589 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5590#endif
5591
Dasari Srinivas7875a302014-09-26 17:50:57 +05305592 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5593 NLMSG_HDRLEN);
5594
5595 if (!skb) {
5596 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5597 return -EINVAL;
5598 }
5599 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5600
5601 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5602 hddLog(LOGE, FL("nla put fail"));
5603 goto nla_put_failure;
5604 }
5605
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305606 ret = cfg80211_vendor_cmd_reply(skb);
5607 EXIT();
5608 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305609
5610nla_put_failure:
5611 kfree_skb(skb);
5612 return -EINVAL;
5613}
5614
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305615static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305616wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5617 struct wireless_dev *wdev,
5618 const void *data, int data_len)
5619{
5620 int ret = 0;
5621
5622 vos_ssr_protect(__func__);
5623 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5624 vos_ssr_unprotect(__func__);
5625
5626 return ret;
5627}
5628
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305629
5630static const struct
5631nla_policy
5632qca_wlan_vendor_wifi_logger_get_ring_data_policy
5633[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5634 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5635 = {.type = NLA_U32 },
5636};
5637
5638static int
5639 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5640 struct wireless_dev *wdev,
5641 const void *data,
5642 int data_len)
5643{
5644 int ret;
5645 VOS_STATUS status;
5646 uint32_t ring_id;
5647 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5648 struct nlattr *tb
5649 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5650
5651 ENTER();
5652
5653 ret = wlan_hdd_validate_context(hdd_ctx);
5654 if (0 != ret) {
5655 return ret;
5656 }
5657
5658 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5659 data, data_len,
5660 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5661 hddLog(LOGE, FL("Invalid attribute"));
5662 return -EINVAL;
5663 }
5664
5665 /* Parse and fetch ring id */
5666 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5667 hddLog(LOGE, FL("attr ATTR failed"));
5668 return -EINVAL;
5669 }
5670
5671 ring_id = nla_get_u32(
5672 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5673
5674 hddLog(LOG1, FL("Bug report triggered by framework"));
5675
5676 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5677 WLAN_LOG_INDICATOR_FRAMEWORK,
5678 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305679 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305680 );
5681 if (VOS_STATUS_SUCCESS != status) {
5682 hddLog(LOGE, FL("Failed to trigger bug report"));
5683
5684 return -EINVAL;
5685 }
5686
5687 return 0;
5688
5689
5690}
5691
5692
5693static int
5694 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5695 struct wireless_dev *wdev,
5696 const void *data,
5697 int data_len)
5698{
5699 int ret = 0;
5700
5701 vos_ssr_protect(__func__);
5702 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5703 wdev, data, data_len);
5704 vos_ssr_unprotect(__func__);
5705
5706 return ret;
5707
5708}
5709
5710
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305711static int
5712__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305713 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305714 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305715{
5716 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5717 uint8_t i, feature_sets, max_feature_sets;
5718 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5719 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305720 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5721 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305722
5723 ENTER();
5724
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305725 ret = wlan_hdd_validate_context(pHddCtx);
5726 if (0 != ret)
5727 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305728 return ret;
5729 }
5730
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305731 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5732 data, data_len, NULL)) {
5733 hddLog(LOGE, FL("Invalid ATTR"));
5734 return -EINVAL;
5735 }
5736
5737 /* Parse and fetch max feature set */
5738 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5739 hddLog(LOGE, FL("Attr max feature set size failed"));
5740 return -EINVAL;
5741 }
5742 max_feature_sets = nla_get_u32(
5743 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5744 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5745
5746 /* Fill feature combination matrix */
5747 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305748 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5749 WIFI_FEATURE_P2P;
5750
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305751 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5752 WIFI_FEATURE_SOFT_AP;
5753
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305754 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5755 WIFI_FEATURE_SOFT_AP;
5756
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305757 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5758 WIFI_FEATURE_SOFT_AP |
5759 WIFI_FEATURE_P2P;
5760
5761 /* Add more feature combinations here */
5762
5763 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5764 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5765 hddLog(LOG1, "Feature set matrix");
5766 for (i = 0; i < feature_sets; i++)
5767 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5768
5769 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5770 sizeof(u32) * feature_sets +
5771 NLMSG_HDRLEN);
5772
5773 if (reply_skb) {
5774 if (nla_put_u32(reply_skb,
5775 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5776 feature_sets) ||
5777 nla_put(reply_skb,
5778 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5779 sizeof(u32) * feature_sets, feature_set_matrix)) {
5780 hddLog(LOGE, FL("nla put fail"));
5781 kfree_skb(reply_skb);
5782 return -EINVAL;
5783 }
5784
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305785 ret = cfg80211_vendor_cmd_reply(reply_skb);
5786 EXIT();
5787 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305788 }
5789 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5790 return -ENOMEM;
5791
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305792}
5793
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305794static int
5795wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5796 struct wireless_dev *wdev,
5797 const void *data, int data_len)
5798{
5799 int ret = 0;
5800
5801 vos_ssr_protect(__func__);
5802 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5803 data_len);
5804 vos_ssr_unprotect(__func__);
5805
5806 return ret;
5807}
5808
c_manjeecfd1efb2015-09-25 19:32:34 +05305809
5810static int
5811__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5812 struct wireless_dev *wdev,
5813 const void *data, int data_len)
5814{
5815 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5816 int ret;
5817 ENTER();
5818
5819 ret = wlan_hdd_validate_context(pHddCtx);
5820 if (0 != ret)
5821 {
5822 return ret;
5823 }
5824
5825 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5826 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5827 {
5828 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5829 return -EINVAL;
5830 }
5831 /*call common API for FW mem dump req*/
5832 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5833
Abhishek Singhc783fa72015-12-09 18:07:34 +05305834 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305835 {
5836 /*indicate to userspace the status of fw mem dump */
5837 wlan_indicate_mem_dump_complete(true);
5838 }
5839 else
5840 {
5841 /*else send failure to userspace */
5842 wlan_indicate_mem_dump_complete(false);
5843 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305844 EXIT();
5845 return ret;
5846}
5847
5848/**
5849 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5850 * @wiphy: pointer to wireless wiphy structure.
5851 * @wdev: pointer to wireless_dev structure.
5852 * @data: Pointer to the NL data.
5853 * @data_len:Length of @data
5854 *
5855 * This is called when wlan driver needs to get the firmware memory dump
5856 * via vendor specific command.
5857 *
5858 * Return: 0 on success, error number otherwise.
5859 */
5860
5861static int
5862wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5863 struct wireless_dev *wdev,
5864 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305865{
5866 int ret = 0;
5867 vos_ssr_protect(__func__);
5868 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5869 data_len);
5870 vos_ssr_unprotect(__func__);
5871 return ret;
5872}
c_manjeecfd1efb2015-09-25 19:32:34 +05305873
Sushant Kaushik8e644982015-09-23 12:18:54 +05305874static const struct
5875nla_policy
5876qca_wlan_vendor_wifi_logger_start_policy
5877[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5878 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5879 = {.type = NLA_U32 },
5880 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5881 = {.type = NLA_U32 },
5882 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5883 = {.type = NLA_U32 },
5884};
5885
5886/**
5887 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5888 * or disable the collection of packet statistics from the firmware
5889 * @wiphy: WIPHY structure pointer
5890 * @wdev: Wireless device structure pointer
5891 * @data: Pointer to the data received
5892 * @data_len: Length of the data received
5893 *
5894 * This function is used to enable or disable the collection of packet
5895 * statistics from the firmware
5896 *
5897 * Return: 0 on success and errno on failure
5898 */
5899static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5900 struct wireless_dev *wdev,
5901 const void *data,
5902 int data_len)
5903{
5904 eHalStatus status;
5905 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5906 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5907 tAniWifiStartLog start_log;
5908
5909 status = wlan_hdd_validate_context(hdd_ctx);
5910 if (0 != status) {
5911 return -EINVAL;
5912 }
5913
5914 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5915 data, data_len,
5916 qca_wlan_vendor_wifi_logger_start_policy)) {
5917 hddLog(LOGE, FL("Invalid attribute"));
5918 return -EINVAL;
5919 }
5920
5921 /* Parse and fetch ring id */
5922 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5923 hddLog(LOGE, FL("attr ATTR failed"));
5924 return -EINVAL;
5925 }
5926 start_log.ringId = nla_get_u32(
5927 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5928 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5929
5930 /* Parse and fetch verbose level */
5931 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5932 hddLog(LOGE, FL("attr verbose_level failed"));
5933 return -EINVAL;
5934 }
5935 start_log.verboseLevel = nla_get_u32(
5936 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5937 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5938
5939 /* Parse and fetch flag */
5940 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5941 hddLog(LOGE, FL("attr flag failed"));
5942 return -EINVAL;
5943 }
5944 start_log.flag = nla_get_u32(
5945 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5946 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5947
5948 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305949 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5950 !vos_isPktStatsEnabled()))
5951
Sushant Kaushik8e644982015-09-23 12:18:54 +05305952 {
5953 hddLog(LOGE, FL("per pkt stats not enabled"));
5954 return -EINVAL;
5955 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305956
Sushant Kaushik33200572015-08-05 16:46:20 +05305957 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305958 return 0;
5959}
5960
5961/**
5962 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5963 * or disable the collection of packet statistics from the firmware
5964 * @wiphy: WIPHY structure pointer
5965 * @wdev: Wireless device structure pointer
5966 * @data: Pointer to the data received
5967 * @data_len: Length of the data received
5968 *
5969 * This function is used to enable or disable the collection of packet
5970 * statistics from the firmware
5971 *
5972 * Return: 0 on success and errno on failure
5973 */
5974static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5975 struct wireless_dev *wdev,
5976 const void *data,
5977 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05305978{
5979 int ret = 0;
5980
5981 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305982
5983 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
5984 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05305985 vos_ssr_unprotect(__func__);
5986
5987 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05305988}
5989
5990
Agarwal Ashish738843c2014-09-25 12:27:56 +05305991static const struct nla_policy
5992wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5993 +1] =
5994{
5995 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5996};
5997
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305998static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305999 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306000 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306001 int data_len)
6002{
6003 struct net_device *dev = wdev->netdev;
6004 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6005 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6006 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6007 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6008 eHalStatus status;
6009 u32 dfsFlag = 0;
6010
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306011 ENTER();
6012
Agarwal Ashish738843c2014-09-25 12:27:56 +05306013 status = wlan_hdd_validate_context(pHddCtx);
6014 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306015 return -EINVAL;
6016 }
6017 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6018 data, data_len,
6019 wlan_hdd_set_no_dfs_flag_config_policy)) {
6020 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6021 return -EINVAL;
6022 }
6023
6024 /* Parse and fetch required bandwidth kbps */
6025 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6026 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6027 return -EINVAL;
6028 }
6029
6030 dfsFlag = nla_get_u32(
6031 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6032 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6033 dfsFlag);
6034
6035 pHddCtx->disable_dfs_flag = dfsFlag;
6036
6037 sme_disable_dfs_channel(hHal, dfsFlag);
6038 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306039
6040 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306041 return 0;
6042}
Atul Mittal115287b2014-07-08 13:26:33 +05306043
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306044static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6045 struct wireless_dev *wdev,
6046 const void *data,
6047 int data_len)
6048{
6049 int ret = 0;
6050
6051 vos_ssr_protect(__func__);
6052 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6053 vos_ssr_unprotect(__func__);
6054
6055 return ret;
6056
6057}
6058
Mukul Sharma2a271632014-10-13 14:59:01 +05306059const struct
6060nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6061{
6062 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6063 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6064};
6065
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306066static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306067 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306068{
6069
6070 u8 bssid[6] = {0};
6071 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6072 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6073 eHalStatus status = eHAL_STATUS_SUCCESS;
6074 v_U32_t isFwrRoamEnabled = FALSE;
6075 int ret;
6076
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306077 ENTER();
6078
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306079 ret = wlan_hdd_validate_context(pHddCtx);
6080 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306081 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306082 }
6083
6084 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6085 data, data_len,
6086 qca_wlan_vendor_attr);
6087 if (ret){
6088 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6089 return -EINVAL;
6090 }
6091
6092 /* Parse and fetch Enable flag */
6093 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6094 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6095 return -EINVAL;
6096 }
6097
6098 isFwrRoamEnabled = nla_get_u32(
6099 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6100
6101 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6102
6103 /* Parse and fetch bssid */
6104 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6105 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6106 return -EINVAL;
6107 }
6108
6109 memcpy(bssid, nla_data(
6110 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6111 sizeof(bssid));
6112 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6113
6114 //Update roaming
6115 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306116 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05306117 return status;
6118}
6119
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306120static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6121 struct wireless_dev *wdev, const void *data, int data_len)
6122{
6123 int ret = 0;
6124
6125 vos_ssr_protect(__func__);
6126 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6127 vos_ssr_unprotect(__func__);
6128
6129 return ret;
6130}
6131
Sushant Kaushik847890c2015-09-28 16:05:17 +05306132static const struct
6133nla_policy
6134qca_wlan_vendor_get_wifi_info_policy[
6135 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6136 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6137 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6138};
6139
6140
6141/**
6142 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6143 * @wiphy: pointer to wireless wiphy structure.
6144 * @wdev: pointer to wireless_dev structure.
6145 * @data: Pointer to the data to be passed via vendor interface
6146 * @data_len:Length of the data to be passed
6147 *
6148 * This is called when wlan driver needs to send wifi driver related info
6149 * (driver/fw version) to the user space application upon request.
6150 *
6151 * Return: Return the Success or Failure code.
6152 */
6153static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6154 struct wireless_dev *wdev,
6155 const void *data, int data_len)
6156{
6157 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6158 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6159 tSirVersionString version;
6160 uint32 version_len;
6161 uint8 attr;
6162 int status;
6163 struct sk_buff *reply_skb = NULL;
6164
6165 if (VOS_FTM_MODE == hdd_get_conparam()) {
6166 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6167 return -EINVAL;
6168 }
6169
6170 status = wlan_hdd_validate_context(hdd_ctx);
6171 if (0 != status) {
6172 hddLog(LOGE, FL("HDD context is not valid"));
6173 return -EINVAL;
6174 }
6175
6176 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6177 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6178 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6179 return -EINVAL;
6180 }
6181
6182 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6183 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6184 QWLAN_VERSIONSTR);
6185 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6186 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6187 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6188 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6189 hdd_ctx->fw_Version);
6190 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6191 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6192 } else {
6193 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6194 return -EINVAL;
6195 }
6196
6197 version_len = strlen(version);
6198 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6199 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6200 if (!reply_skb) {
6201 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6202 return -ENOMEM;
6203 }
6204
6205 if (nla_put(reply_skb, attr, version_len, version)) {
6206 hddLog(LOGE, FL("nla put fail"));
6207 kfree_skb(reply_skb);
6208 return -EINVAL;
6209 }
6210
6211 return cfg80211_vendor_cmd_reply(reply_skb);
6212}
6213
6214/**
6215 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6216 * @wiphy: pointer to wireless wiphy structure.
6217 * @wdev: pointer to wireless_dev structure.
6218 * @data: Pointer to the data to be passed via vendor interface
6219 * @data_len:Length of the data to be passed
6220 * @data_len: Length of the data received
6221 *
6222 * This function is used to enable or disable the collection of packet
6223 * statistics from the firmware
6224 *
6225 * Return: 0 on success and errno on failure
6226 */
6227
6228static int
6229wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6230 struct wireless_dev *wdev,
6231 const void *data, int data_len)
6232
6233
6234{
6235 int ret = 0;
6236
6237 vos_ssr_protect(__func__);
6238 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6239 wdev, data, data_len);
6240 vos_ssr_unprotect(__func__);
6241
6242 return ret;
6243}
6244
6245
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306246/*
6247 * define short names for the global vendor params
6248 * used by __wlan_hdd_cfg80211_monitor_rssi()
6249 */
6250#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6251#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6252#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6253#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6254#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6255
6256/**---------------------------------------------------------------------------
6257
6258 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6259 monitor start is completed successfully.
6260
6261 \return - None
6262
6263 --------------------------------------------------------------------------*/
6264void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6265{
6266 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6267
6268 if (NULL == pHddCtx)
6269 {
6270 hddLog(VOS_TRACE_LEVEL_ERROR,
6271 "%s: HDD context is NULL",__func__);
6272 return;
6273 }
6274
6275 if (VOS_STATUS_SUCCESS == status)
6276 {
6277 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6278 }
6279 else
6280 {
6281 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6282 }
6283
6284 return;
6285}
6286
6287/**---------------------------------------------------------------------------
6288
6289 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6290 stop is completed successfully.
6291
6292 \return - None
6293
6294 --------------------------------------------------------------------------*/
6295void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6296{
6297 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6298
6299 if (NULL == pHddCtx)
6300 {
6301 hddLog(VOS_TRACE_LEVEL_ERROR,
6302 "%s: HDD context is NULL",__func__);
6303 return;
6304 }
6305
6306 if (VOS_STATUS_SUCCESS == status)
6307 {
6308 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6309 }
6310 else
6311 {
6312 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6313 }
6314
6315 return;
6316}
6317
6318/**
6319 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6320 * @wiphy: Pointer to wireless phy
6321 * @wdev: Pointer to wireless device
6322 * @data: Pointer to data
6323 * @data_len: Data length
6324 *
6325 * Return: 0 on success, negative errno on failure
6326 */
6327
6328static int
6329__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6330 struct wireless_dev *wdev,
6331 const void *data,
6332 int data_len)
6333{
6334 struct net_device *dev = wdev->netdev;
6335 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6336 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6337 hdd_station_ctx_t *pHddStaCtx;
6338 struct nlattr *tb[PARAM_MAX + 1];
6339 tpSirRssiMonitorReq pReq;
6340 eHalStatus status;
6341 int ret;
6342 uint32_t control;
6343 static const struct nla_policy policy[PARAM_MAX + 1] = {
6344 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6345 [PARAM_CONTROL] = { .type = NLA_U32 },
6346 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6347 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6348 };
6349
6350 ENTER();
6351
6352 ret = wlan_hdd_validate_context(hdd_ctx);
6353 if (0 != ret) {
6354 return -EINVAL;
6355 }
6356
6357 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6358 hddLog(LOGE, FL("Not in Connected state!"));
6359 return -ENOTSUPP;
6360 }
6361
6362 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6363 hddLog(LOGE, FL("Invalid ATTR"));
6364 return -EINVAL;
6365 }
6366
6367 if (!tb[PARAM_REQUEST_ID]) {
6368 hddLog(LOGE, FL("attr request id failed"));
6369 return -EINVAL;
6370 }
6371
6372 if (!tb[PARAM_CONTROL]) {
6373 hddLog(LOGE, FL("attr control failed"));
6374 return -EINVAL;
6375 }
6376
6377 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6378
6379 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6380 if(NULL == pReq)
6381 {
6382 hddLog(LOGE,
6383 FL("vos_mem_alloc failed "));
6384 return eHAL_STATUS_FAILED_ALLOC;
6385 }
6386 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6387
6388 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6389 pReq->sessionId = pAdapter->sessionId;
6390 pReq->rssiMonitorCbContext = hdd_ctx;
6391 control = nla_get_u32(tb[PARAM_CONTROL]);
6392 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6393
6394 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6395 pReq->requestId, pReq->sessionId, control);
6396
6397 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6398 if (!tb[PARAM_MIN_RSSI]) {
6399 hddLog(LOGE, FL("attr min rssi failed"));
6400 return -EINVAL;
6401 }
6402
6403 if (!tb[PARAM_MAX_RSSI]) {
6404 hddLog(LOGE, FL("attr max rssi failed"));
6405 return -EINVAL;
6406 }
6407
6408 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6409 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6410 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6411
6412 if (!(pReq->minRssi < pReq->maxRssi)) {
6413 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6414 pReq->minRssi, pReq->maxRssi);
6415 return -EINVAL;
6416 }
6417 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6418 pReq->minRssi, pReq->maxRssi);
6419 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6420
6421 }
6422 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6423 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6424 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6425 }
6426 else {
6427 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
6428 return -EINVAL;
6429 }
6430
6431 if (!HAL_STATUS_SUCCESS(status)) {
6432 hddLog(LOGE,
6433 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
6434 return -EINVAL;
6435 }
6436
6437 return 0;
6438}
6439
6440/*
6441 * done with short names for the global vendor params
6442 * used by __wlan_hdd_cfg80211_monitor_rssi()
6443 */
6444#undef PARAM_MAX
6445#undef PARAM_CONTROL
6446#undef PARAM_REQUEST_ID
6447#undef PARAM_MAX_RSSI
6448#undef PARAM_MIN_RSSI
6449
6450/**
6451 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6452 * @wiphy: wiphy structure pointer
6453 * @wdev: Wireless device structure pointer
6454 * @data: Pointer to the data received
6455 * @data_len: Length of @data
6456 *
6457 * Return: 0 on success; errno on failure
6458 */
6459static int
6460wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6461 const void *data, int data_len)
6462{
6463 int ret;
6464
6465 vos_ssr_protect(__func__);
6466 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6467 vos_ssr_unprotect(__func__);
6468
6469 return ret;
6470}
6471
6472/**
6473 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6474 * @hddctx: HDD context
6475 * @data: rssi breached event data
6476 *
6477 * This function reads the rssi breached event %data and fill in the skb with
6478 * NL attributes and send up the NL event.
6479 * This callback execute in atomic context and must not invoke any
6480 * blocking calls.
6481 *
6482 * Return: none
6483 */
6484void hdd_rssi_threshold_breached_cb(void *hddctx,
6485 struct rssi_breach_event *data)
6486{
6487 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6488 int status;
6489 struct sk_buff *skb;
6490
6491 ENTER();
6492 status = wlan_hdd_validate_context(pHddCtx);
6493
6494 if (0 != status) {
6495 return;
6496 }
6497
6498 if (!data) {
6499 hddLog(LOGE, FL("data is null"));
6500 return;
6501 }
6502
6503 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6504#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6505 NULL,
6506#endif
6507 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6508 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6509 GFP_KERNEL);
6510
6511 if (!skb) {
6512 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6513 return;
6514 }
6515
6516 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6517 data->request_id, data->curr_rssi);
6518 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6519 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6520
6521 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6522 data->request_id) ||
6523 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6524 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6525 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6526 data->curr_rssi)) {
6527 hddLog(LOGE, FL("nla put fail"));
6528 goto fail;
6529 }
6530
6531 cfg80211_vendor_event(skb, GFP_KERNEL);
6532 return;
6533
6534fail:
6535 kfree_skb(skb);
6536 return;
6537}
6538
6539
6540
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306541/**
6542 * __wlan_hdd_cfg80211_setband() - set band
6543 * @wiphy: Pointer to wireless phy
6544 * @wdev: Pointer to wireless device
6545 * @data: Pointer to data
6546 * @data_len: Data length
6547 *
6548 * Return: 0 on success, negative errno on failure
6549 */
6550static int
6551__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6552 struct wireless_dev *wdev,
6553 const void *data,
6554 int data_len)
6555{
6556 struct net_device *dev = wdev->netdev;
6557 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6558 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6559 int ret;
6560 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6561 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6562
6563 ENTER();
6564
6565 ret = wlan_hdd_validate_context(hdd_ctx);
6566 if (0 != ret) {
6567 hddLog(LOGE, FL("HDD context is not valid"));
6568 return ret;
6569 }
6570
6571 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6572 policy)) {
6573 hddLog(LOGE, FL("Invalid ATTR"));
6574 return -EINVAL;
6575 }
6576
6577 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6578 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6579 return -EINVAL;
6580 }
6581
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306582 hdd_ctx->isSetBandByNL = TRUE;
6583 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306584 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306585 hdd_ctx->isSetBandByNL = FALSE;
6586
6587 EXIT();
6588 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306589}
6590
6591/**
6592 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6593 * @wiphy: wiphy structure pointer
6594 * @wdev: Wireless device structure pointer
6595 * @data: Pointer to the data received
6596 * @data_len: Length of @data
6597 *
6598 * Return: 0 on success; errno on failure
6599 */
6600static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6601 struct wireless_dev *wdev,
6602 const void *data,
6603 int data_len)
6604{
6605 int ret = 0;
6606
6607 vos_ssr_protect(__func__);
6608 ret = __wlan_hdd_cfg80211_setband(wiphy,
6609 wdev, data, data_len);
6610 vos_ssr_unprotect(__func__);
6611
6612 return ret;
6613}
6614
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306615#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6616/**
6617 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6618 * @hdd_ctx: HDD context
6619 * @request_id: [input] request id
6620 * @pattern_id: [output] pattern id
6621 *
6622 * This function loops through request id to pattern id array
6623 * if the slot is available, store the request id and return pattern id
6624 * if entry exists, return the pattern id
6625 *
6626 * Return: 0 on success and errno on failure
6627 */
6628static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6629 uint32_t request_id,
6630 uint8_t *pattern_id)
6631{
6632 uint32_t i;
6633
6634 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6635 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6636 {
6637 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6638 {
6639 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6640 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6641 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6642 return 0;
6643 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6644 request_id) {
6645 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6646 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6647 return 0;
6648 }
6649 }
6650 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6651 return -EINVAL;
6652}
6653
6654/**
6655 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6656 * @hdd_ctx: HDD context
6657 * @request_id: [input] request id
6658 * @pattern_id: [output] pattern id
6659 *
6660 * This function loops through request id to pattern id array
6661 * reset request id to 0 (slot available again) and
6662 * return pattern id
6663 *
6664 * Return: 0 on success and errno on failure
6665 */
6666static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6667 uint32_t request_id,
6668 uint8_t *pattern_id)
6669{
6670 uint32_t i;
6671
6672 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6673 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6674 {
6675 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6676 {
6677 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6678 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6679 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6680 return 0;
6681 }
6682 }
6683 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6684 return -EINVAL;
6685}
6686
6687
6688/*
6689 * define short names for the global vendor params
6690 * used by __wlan_hdd_cfg80211_offloaded_packets()
6691 */
6692#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6693#define PARAM_REQUEST_ID \
6694 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6695#define PARAM_CONTROL \
6696 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6697#define PARAM_IP_PACKET \
6698 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6699#define PARAM_SRC_MAC_ADDR \
6700 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6701#define PARAM_DST_MAC_ADDR \
6702 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6703#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6704
6705/**
6706 * wlan_hdd_add_tx_ptrn() - add tx pattern
6707 * @adapter: adapter pointer
6708 * @hdd_ctx: hdd context
6709 * @tb: nl attributes
6710 *
6711 * This function reads the NL attributes and forms a AddTxPtrn message
6712 * posts it to SME.
6713 *
6714 */
6715static int
6716wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6717 struct nlattr **tb)
6718{
6719 struct sSirAddPeriodicTxPtrn *add_req;
6720 eHalStatus status;
6721 uint32_t request_id, ret, len;
6722 uint8_t pattern_id = 0;
6723 v_MACADDR_t dst_addr;
6724 uint16_t eth_type = htons(ETH_P_IP);
6725
6726 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6727 {
6728 hddLog(LOGE, FL("Not in Connected state!"));
6729 return -ENOTSUPP;
6730 }
6731
6732 add_req = vos_mem_malloc(sizeof(*add_req));
6733 if (!add_req)
6734 {
6735 hddLog(LOGE, FL("memory allocation failed"));
6736 return -ENOMEM;
6737 }
6738
6739 /* Parse and fetch request Id */
6740 if (!tb[PARAM_REQUEST_ID])
6741 {
6742 hddLog(LOGE, FL("attr request id failed"));
6743 goto fail;
6744 }
6745
6746 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6747 hddLog(LOG1, FL("Request Id: %u"), request_id);
6748 if (request_id == 0)
6749 {
6750 hddLog(LOGE, FL("request_id cannot be zero"));
6751 return -EINVAL;
6752 }
6753
6754 if (!tb[PARAM_PERIOD])
6755 {
6756 hddLog(LOGE, FL("attr period failed"));
6757 goto fail;
6758 }
6759 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6760 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6761 if (add_req->usPtrnIntervalMs == 0)
6762 {
6763 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6764 goto fail;
6765 }
6766
6767 if (!tb[PARAM_SRC_MAC_ADDR])
6768 {
6769 hddLog(LOGE, FL("attr source mac address failed"));
6770 goto fail;
6771 }
6772 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6773 VOS_MAC_ADDR_SIZE);
6774 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6775 MAC_ADDR_ARRAY(add_req->macAddress));
6776
6777 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6778 VOS_MAC_ADDR_SIZE))
6779 {
6780 hddLog(LOGE,
6781 FL("input src mac address and connected ap bssid are different"));
6782 goto fail;
6783 }
6784
6785 if (!tb[PARAM_DST_MAC_ADDR])
6786 {
6787 hddLog(LOGE, FL("attr dst mac address failed"));
6788 goto fail;
6789 }
6790 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6791 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6792 MAC_ADDR_ARRAY(dst_addr.bytes));
6793
6794 if (!tb[PARAM_IP_PACKET])
6795 {
6796 hddLog(LOGE, FL("attr ip packet failed"));
6797 goto fail;
6798 }
6799 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6800 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6801
6802 if (add_req->ucPtrnSize < 0 ||
6803 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6804 HDD_ETH_HEADER_LEN))
6805 {
6806 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6807 add_req->ucPtrnSize);
6808 goto fail;
6809 }
6810
6811 len = 0;
6812 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6813 len += VOS_MAC_ADDR_SIZE;
6814 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6815 VOS_MAC_ADDR_SIZE);
6816 len += VOS_MAC_ADDR_SIZE;
6817 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6818 len += 2;
6819
6820 /*
6821 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6822 * ------------------------------------------------------------
6823 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6824 * ------------------------------------------------------------
6825 */
6826 vos_mem_copy(&add_req->ucPattern[len],
6827 nla_data(tb[PARAM_IP_PACKET]),
6828 add_req->ucPtrnSize);
6829 add_req->ucPtrnSize += len;
6830
6831 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6832 add_req->ucPattern, add_req->ucPtrnSize);
6833
6834 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6835 if (ret)
6836 {
6837 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6838 goto fail;
6839 }
6840 add_req->ucPtrnId = pattern_id;
6841 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6842
6843 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6844 if (!HAL_STATUS_SUCCESS(status))
6845 {
6846 hddLog(LOGE,
6847 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6848 goto fail;
6849 }
6850
6851 EXIT();
6852 vos_mem_free(add_req);
6853 return 0;
6854
6855fail:
6856 vos_mem_free(add_req);
6857 return -EINVAL;
6858}
6859
6860/**
6861 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6862 * @adapter: adapter pointer
6863 * @hdd_ctx: hdd context
6864 * @tb: nl attributes
6865 *
6866 * This function reads the NL attributes and forms a DelTxPtrn message
6867 * posts it to SME.
6868 *
6869 */
6870static int
6871wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6872 struct nlattr **tb)
6873{
6874 struct sSirDelPeriodicTxPtrn *del_req;
6875 eHalStatus status;
6876 uint32_t request_id, ret;
6877 uint8_t pattern_id = 0;
6878
6879 /* Parse and fetch request Id */
6880 if (!tb[PARAM_REQUEST_ID])
6881 {
6882 hddLog(LOGE, FL("attr request id failed"));
6883 return -EINVAL;
6884 }
6885 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6886 if (request_id == 0)
6887 {
6888 hddLog(LOGE, FL("request_id cannot be zero"));
6889 return -EINVAL;
6890 }
6891
6892 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6893 if (ret)
6894 {
6895 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6896 return -EINVAL;
6897 }
6898
6899 del_req = vos_mem_malloc(sizeof(*del_req));
6900 if (!del_req)
6901 {
6902 hddLog(LOGE, FL("memory allocation failed"));
6903 return -ENOMEM;
6904 }
6905
6906 vos_mem_set(del_req, sizeof(*del_req), 0);
6907 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6908 VOS_MAC_ADDR_SIZE);
6909 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6910 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6911 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6912 request_id, pattern_id, del_req->ucPatternIdBitmap);
6913
6914 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6915 if (!HAL_STATUS_SUCCESS(status))
6916 {
6917 hddLog(LOGE,
6918 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6919 goto fail;
6920 }
6921
6922 EXIT();
6923 vos_mem_free(del_req);
6924 return 0;
6925
6926fail:
6927 vos_mem_free(del_req);
6928 return -EINVAL;
6929}
6930
6931
6932/**
6933 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6934 * @wiphy: Pointer to wireless phy
6935 * @wdev: Pointer to wireless device
6936 * @data: Pointer to data
6937 * @data_len: Data length
6938 *
6939 * Return: 0 on success, negative errno on failure
6940 */
6941static int
6942__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6943 struct wireless_dev *wdev,
6944 const void *data,
6945 int data_len)
6946{
6947 struct net_device *dev = wdev->netdev;
6948 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6949 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6950 struct nlattr *tb[PARAM_MAX + 1];
6951 uint8_t control;
6952 int ret;
6953 static const struct nla_policy policy[PARAM_MAX + 1] =
6954 {
6955 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6956 [PARAM_CONTROL] = { .type = NLA_U32 },
6957 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
6958 .len = VOS_MAC_ADDR_SIZE },
6959 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
6960 .len = VOS_MAC_ADDR_SIZE },
6961 [PARAM_PERIOD] = { .type = NLA_U32 },
6962 };
6963
6964 ENTER();
6965
6966 ret = wlan_hdd_validate_context(hdd_ctx);
6967 if (0 != ret)
6968 {
6969 hddLog(LOGE, FL("HDD context is not valid"));
6970 return ret;
6971 }
6972
6973 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
6974 {
6975 hddLog(LOGE,
6976 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
6977 return -ENOTSUPP;
6978 }
6979
6980 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
6981 {
6982 hddLog(LOGE, FL("Invalid ATTR"));
6983 return -EINVAL;
6984 }
6985
6986 if (!tb[PARAM_CONTROL])
6987 {
6988 hddLog(LOGE, FL("attr control failed"));
6989 return -EINVAL;
6990 }
6991 control = nla_get_u32(tb[PARAM_CONTROL]);
6992 hddLog(LOG1, FL("Control: %d"), control);
6993
6994 if (control == WLAN_START_OFFLOADED_PACKETS)
6995 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
6996 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
6997 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
6998 else
6999 {
7000 hddLog(LOGE, FL("Invalid control: %d"), control);
7001 return -EINVAL;
7002 }
7003}
7004
7005/*
7006 * done with short names for the global vendor params
7007 * used by __wlan_hdd_cfg80211_offloaded_packets()
7008 */
7009#undef PARAM_MAX
7010#undef PARAM_REQUEST_ID
7011#undef PARAM_CONTROL
7012#undef PARAM_IP_PACKET
7013#undef PARAM_SRC_MAC_ADDR
7014#undef PARAM_DST_MAC_ADDR
7015#undef PARAM_PERIOD
7016
7017/**
7018 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7019 * @wiphy: wiphy structure pointer
7020 * @wdev: Wireless device structure pointer
7021 * @data: Pointer to the data received
7022 * @data_len: Length of @data
7023 *
7024 * Return: 0 on success; errno on failure
7025 */
7026static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7027 struct wireless_dev *wdev,
7028 const void *data,
7029 int data_len)
7030{
7031 int ret = 0;
7032
7033 vos_ssr_protect(__func__);
7034 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7035 wdev, data, data_len);
7036 vos_ssr_unprotect(__func__);
7037
7038 return ret;
7039}
7040#endif
7041
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307042static const struct
7043nla_policy
7044qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7045 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7046};
7047
7048/**
7049 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7050 * get link properties like nss, rate flags and operating frequency for
7051 * the connection with the given peer.
7052 * @wiphy: WIPHY structure pointer
7053 * @wdev: Wireless device structure pointer
7054 * @data: Pointer to the data received
7055 * @data_len: Length of the data received
7056 *
7057 * This function return the above link properties on success.
7058 *
7059 * Return: 0 on success and errno on failure
7060 */
7061static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7062 struct wireless_dev *wdev,
7063 const void *data,
7064 int data_len)
7065{
7066 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7067 struct net_device *dev = wdev->netdev;
7068 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7069 hdd_station_ctx_t *hdd_sta_ctx;
7070 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7071 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7072 uint32_t sta_id;
7073 struct sk_buff *reply_skb;
7074 uint32_t rate_flags = 0;
7075 uint8_t nss;
7076 uint8_t final_rate_flags = 0;
7077 uint32_t freq;
7078 v_CONTEXT_t pVosContext = NULL;
7079 ptSapContext pSapCtx = NULL;
7080
7081 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7083 return -EINVAL;
7084 }
7085
7086 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7087 qca_wlan_vendor_attr_policy)) {
7088 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7089 return -EINVAL;
7090 }
7091
7092 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7093 hddLog(VOS_TRACE_LEVEL_ERROR,
7094 FL("Attribute peerMac not provided for mode=%d"),
7095 adapter->device_mode);
7096 return -EINVAL;
7097 }
7098
7099 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7100 sizeof(peer_mac));
7101 hddLog(VOS_TRACE_LEVEL_INFO,
7102 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7103 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7104
7105 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7106 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7107 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7108 if ((hdd_sta_ctx->conn_info.connState !=
7109 eConnectionState_Associated) ||
7110 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7111 VOS_MAC_ADDRESS_LEN)) {
7112 hddLog(VOS_TRACE_LEVEL_ERROR,
7113 FL("Not Associated to mac "MAC_ADDRESS_STR),
7114 MAC_ADDR_ARRAY(peer_mac));
7115 return -EINVAL;
7116 }
7117
7118 nss = 1; //pronto supports only one spatial stream
7119 freq = vos_chan_to_freq(
7120 hdd_sta_ctx->conn_info.operationChannel);
7121 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7122
7123 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7124 adapter->device_mode == WLAN_HDD_SOFTAP) {
7125
7126 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7127 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7128 if(pSapCtx == NULL){
7129 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7130 FL("psapCtx is NULL"));
7131 return -ENOENT;
7132 }
7133
7134
7135 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7136 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7137 !vos_is_macaddr_broadcast(
7138 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7139 vos_mem_compare(
7140 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7141 peer_mac, VOS_MAC_ADDRESS_LEN))
7142 break;
7143 }
7144
7145 if (WLAN_MAX_STA_COUNT == sta_id) {
7146 hddLog(VOS_TRACE_LEVEL_ERROR,
7147 FL("No active peer with mac="MAC_ADDRESS_STR),
7148 MAC_ADDR_ARRAY(peer_mac));
7149 return -EINVAL;
7150 }
7151
7152 nss = 1; //pronto supports only one spatial stream
7153 freq = vos_chan_to_freq(
7154 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7155 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7156 } else {
7157 hddLog(VOS_TRACE_LEVEL_ERROR,
7158 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7159 MAC_ADDR_ARRAY(peer_mac));
7160 return -EINVAL;
7161 }
7162
7163 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7164 if (rate_flags & eHAL_TX_RATE_VHT80) {
7165 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7166 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7167 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7168 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7169 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7170 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7171 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7172 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7173 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7174 if (rate_flags & eHAL_TX_RATE_HT40)
7175 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7176 }
7177
7178 if (rate_flags & eHAL_TX_RATE_SGI) {
7179 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7180 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7181 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7182 }
7183 }
7184
7185 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7186 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7187
7188 if (NULL == reply_skb) {
7189 hddLog(VOS_TRACE_LEVEL_ERROR,
7190 FL("getLinkProperties: skb alloc failed"));
7191 return -EINVAL;
7192 }
7193
7194 if (nla_put_u8(reply_skb,
7195 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7196 nss) ||
7197 nla_put_u8(reply_skb,
7198 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7199 final_rate_flags) ||
7200 nla_put_u32(reply_skb,
7201 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7202 freq)) {
7203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7204 kfree_skb(reply_skb);
7205 return -EINVAL;
7206 }
7207
7208 return cfg80211_vendor_cmd_reply(reply_skb);
7209}
7210
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307211#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7212#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7213#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7214#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307215#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7216 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307217
7218/**
7219 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7220 * vendor command
7221 *
7222 * @wiphy: wiphy device pointer
7223 * @wdev: wireless device pointer
7224 * @data: Vendor command data buffer
7225 * @data_len: Buffer length
7226 *
7227 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7228 *
7229 * Return: EOK or other error codes.
7230 */
7231
7232static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7233 struct wireless_dev *wdev,
7234 const void *data,
7235 int data_len)
7236{
7237 struct net_device *dev = wdev->netdev;
7238 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7239 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7240 hdd_station_ctx_t *pHddStaCtx;
7241 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7242 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307243 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307244 eHalStatus status;
7245 int ret_val;
7246 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7247 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7248 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307249 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7250 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7251 { .type = NLA_U32},
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307252 };
7253
7254 ENTER();
7255
7256 if (VOS_FTM_MODE == hdd_get_conparam()) {
7257 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7258 return -EINVAL;
7259 }
7260
7261 ret_val = wlan_hdd_validate_context(pHddCtx);
7262 if (ret_val) {
7263 return ret_val;
7264 }
7265
7266 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7267
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307268 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7269 hddLog(LOGE, FL("Invalid ATTR"));
7270 return -EINVAL;
7271 }
7272
7273 /* check the Wifi Capability */
7274 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7275 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7276 {
7277 hddLog(VOS_TRACE_LEVEL_ERROR,
7278 FL("WIFICONFIG not supported by Firmware"));
7279 return -EINVAL;
7280 }
7281
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307282 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7283 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7284 modifyRoamParamsReq.value =
7285 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7286
7287 if (eHAL_STATUS_SUCCESS !=
7288 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7289 {
7290 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7291 ret_val = -EINVAL;
7292 }
7293 return ret_val;
7294 }
7295
7296 /* Moved this down in order to provide provision to set beacon
7297 * miss penalty count irrespective of connection state.
7298 */
7299 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7300 hddLog(LOGE, FL("Not in Connected state!"));
7301 return -ENOTSUPP;
7302 }
7303
7304 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307305
7306 if (!pReq) {
7307 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7308 "%s: Not able to allocate memory for tSetWifiConfigParams",
7309 __func__);
7310 return eHAL_STATUS_E_MALLOC_FAILED;
7311 }
7312
7313 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7314
7315 pReq->sessionId = pAdapter->sessionId;
7316 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7317
7318 if (tb[PARAM_MODULATED_DTIM]) {
7319 pReq->paramValue = nla_get_u32(
7320 tb[PARAM_MODULATED_DTIM]);
7321 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7322 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307323 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307324 hdd_set_pwrparams(pHddCtx);
7325 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7326 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7327
7328 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7329 iw_full_power_cbfn, pAdapter,
7330 eSME_FULL_PWR_NEEDED_BY_HDD);
7331 }
7332 else
7333 {
7334 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7335 }
7336 }
7337
7338 if (tb[PARAM_STATS_AVG_FACTOR]) {
7339 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7340 pReq->paramValue = nla_get_u16(
7341 tb[PARAM_STATS_AVG_FACTOR]);
7342 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7343 pReq->paramType, pReq->paramValue);
7344 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7345
7346 if (eHAL_STATUS_SUCCESS != status)
7347 {
7348 vos_mem_free(pReq);
7349 pReq = NULL;
7350 ret_val = -EPERM;
7351 return ret_val;
7352 }
7353 }
7354
7355
7356 if (tb[PARAM_GUARD_TIME]) {
7357 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7358 pReq->paramValue = nla_get_u32(
7359 tb[PARAM_GUARD_TIME]);
7360 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7361 pReq->paramType, pReq->paramValue);
7362 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7363
7364 if (eHAL_STATUS_SUCCESS != status)
7365 {
7366 vos_mem_free(pReq);
7367 pReq = NULL;
7368 ret_val = -EPERM;
7369 return ret_val;
7370 }
7371
7372 }
7373
7374 EXIT();
7375 return ret_val;
7376}
7377
7378/**
7379 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7380 * vendor command
7381 *
7382 * @wiphy: wiphy device pointer
7383 * @wdev: wireless device pointer
7384 * @data: Vendor command data buffer
7385 * @data_len: Buffer length
7386 *
7387 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7388 *
7389 * Return: EOK or other error codes.
7390 */
7391static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7392 struct wireless_dev *wdev,
7393 const void *data,
7394 int data_len)
7395{
7396 int ret;
7397
7398 vos_ssr_protect(__func__);
7399 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7400 data, data_len);
7401 vos_ssr_unprotect(__func__);
7402
7403 return ret;
7404}
Sunil Duttc69bccb2014-05-26 21:30:20 +05307405const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7406{
Mukul Sharma2a271632014-10-13 14:59:01 +05307407 {
7408 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7409 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7410 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7411 WIPHY_VENDOR_CMD_NEED_NETDEV |
7412 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307413 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307414 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307415
7416 {
7417 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7418 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7419 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7420 WIPHY_VENDOR_CMD_NEED_NETDEV |
7421 WIPHY_VENDOR_CMD_NEED_RUNNING,
7422 .doit = wlan_hdd_cfg80211_nan_request
7423 },
7424
Sunil Duttc69bccb2014-05-26 21:30:20 +05307425#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7426 {
7427 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7428 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7429 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7430 WIPHY_VENDOR_CMD_NEED_NETDEV |
7431 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307432 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307433 },
7434
7435 {
7436 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7437 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7438 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7439 WIPHY_VENDOR_CMD_NEED_NETDEV |
7440 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307441 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307442 },
7443
7444 {
7445 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7446 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7447 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7448 WIPHY_VENDOR_CMD_NEED_NETDEV |
7449 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307450 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307451 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307452#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307453#ifdef WLAN_FEATURE_EXTSCAN
7454 {
7455 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7456 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7457 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7458 WIPHY_VENDOR_CMD_NEED_NETDEV |
7459 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307460 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307461 },
7462 {
7463 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7464 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7465 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7466 WIPHY_VENDOR_CMD_NEED_NETDEV |
7467 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307468 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307469 },
7470 {
7471 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7472 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7473 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7474 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307475 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307476 },
7477 {
7478 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7479 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7480 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7481 WIPHY_VENDOR_CMD_NEED_NETDEV |
7482 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307483 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307484 },
7485 {
7486 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7487 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7488 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7489 WIPHY_VENDOR_CMD_NEED_NETDEV |
7490 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307491 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307492 },
7493 {
7494 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7495 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7496 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7497 WIPHY_VENDOR_CMD_NEED_NETDEV |
7498 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307499 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307500 },
7501 {
7502 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7503 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7504 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7505 WIPHY_VENDOR_CMD_NEED_NETDEV |
7506 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307507 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307508 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307509 {
7510 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7511 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7512 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7513 WIPHY_VENDOR_CMD_NEED_NETDEV |
7514 WIPHY_VENDOR_CMD_NEED_RUNNING,
7515 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7516 },
7517 {
7518 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7519 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7520 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7521 WIPHY_VENDOR_CMD_NEED_NETDEV |
7522 WIPHY_VENDOR_CMD_NEED_RUNNING,
7523 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7524 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307525#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307526/*EXT TDLS*/
7527 {
7528 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7529 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7530 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7531 WIPHY_VENDOR_CMD_NEED_NETDEV |
7532 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307533 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307534 },
7535 {
7536 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7537 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7538 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7539 WIPHY_VENDOR_CMD_NEED_NETDEV |
7540 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307541 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307542 },
7543 {
7544 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7545 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7546 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7547 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307548 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307549 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307550 {
7551 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7552 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7553 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7554 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307555 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307556 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307557 {
7558 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7559 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7560 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7561 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307562 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307563 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307564 {
7565 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7566 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7567 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7568 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307569 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307570 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307571 {
7572 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7573 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7574 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7575 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307576 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307577 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307578 {
7579 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307580 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7581 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7582 WIPHY_VENDOR_CMD_NEED_NETDEV |
7583 WIPHY_VENDOR_CMD_NEED_RUNNING,
7584 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7585 },
7586 {
7587 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307588 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7589 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7590 WIPHY_VENDOR_CMD_NEED_NETDEV |
7591 WIPHY_VENDOR_CMD_NEED_RUNNING,
7592 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307593 },
7594 {
7595 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7596 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7597 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7598 WIPHY_VENDOR_CMD_NEED_NETDEV,
7599 .doit = wlan_hdd_cfg80211_wifi_logger_start
7600 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307601 {
7602 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7603 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7604 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7605 WIPHY_VENDOR_CMD_NEED_NETDEV|
7606 WIPHY_VENDOR_CMD_NEED_RUNNING,
7607 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307608 },
7609 {
7610 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7611 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7612 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7613 WIPHY_VENDOR_CMD_NEED_NETDEV |
7614 WIPHY_VENDOR_CMD_NEED_RUNNING,
7615 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307616 },
7617 {
7618 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7619 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7620 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7621 WIPHY_VENDOR_CMD_NEED_NETDEV |
7622 WIPHY_VENDOR_CMD_NEED_RUNNING,
7623 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307624 },
7625#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7626 {
7627 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7628 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7629 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7630 WIPHY_VENDOR_CMD_NEED_NETDEV |
7631 WIPHY_VENDOR_CMD_NEED_RUNNING,
7632 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307633 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307634#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307635 {
7636 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7637 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7638 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7639 WIPHY_VENDOR_CMD_NEED_NETDEV |
7640 WIPHY_VENDOR_CMD_NEED_RUNNING,
7641 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307642 },
7643 {
7644 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7645 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7646 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7647 WIPHY_VENDOR_CMD_NEED_NETDEV |
7648 WIPHY_VENDOR_CMD_NEED_RUNNING,
7649 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307650 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05307651};
7652
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007653/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307654static const
7655struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007656{
7657#ifdef FEATURE_WLAN_CH_AVOID
7658 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307659 .vendor_id = QCA_NL80211_VENDOR_ID,
7660 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007661 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307662#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7663#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7664 {
7665 /* Index = 1*/
7666 .vendor_id = QCA_NL80211_VENDOR_ID,
7667 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7668 },
7669 {
7670 /* Index = 2*/
7671 .vendor_id = QCA_NL80211_VENDOR_ID,
7672 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7673 },
7674 {
7675 /* Index = 3*/
7676 .vendor_id = QCA_NL80211_VENDOR_ID,
7677 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7678 },
7679 {
7680 /* Index = 4*/
7681 .vendor_id = QCA_NL80211_VENDOR_ID,
7682 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7683 },
7684 {
7685 /* Index = 5*/
7686 .vendor_id = QCA_NL80211_VENDOR_ID,
7687 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7688 },
7689 {
7690 /* Index = 6*/
7691 .vendor_id = QCA_NL80211_VENDOR_ID,
7692 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7693 },
7694#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307695#ifdef WLAN_FEATURE_EXTSCAN
7696 {
7697 .vendor_id = QCA_NL80211_VENDOR_ID,
7698 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7699 },
7700 {
7701 .vendor_id = QCA_NL80211_VENDOR_ID,
7702 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7703 },
7704 {
7705 .vendor_id = QCA_NL80211_VENDOR_ID,
7706 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7707 },
7708 {
7709 .vendor_id = QCA_NL80211_VENDOR_ID,
7710 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7711 },
7712 {
7713 .vendor_id = QCA_NL80211_VENDOR_ID,
7714 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7715 },
7716 {
7717 .vendor_id = QCA_NL80211_VENDOR_ID,
7718 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7719 },
7720 {
7721 .vendor_id = QCA_NL80211_VENDOR_ID,
7722 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7723 },
7724 {
7725 .vendor_id = QCA_NL80211_VENDOR_ID,
7726 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7727 },
7728 {
7729 .vendor_id = QCA_NL80211_VENDOR_ID,
7730 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7731 },
7732 {
7733 .vendor_id = QCA_NL80211_VENDOR_ID,
7734 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7735 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307736 {
7737 .vendor_id = QCA_NL80211_VENDOR_ID,
7738 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7739 },
7740 {
7741 .vendor_id = QCA_NL80211_VENDOR_ID,
7742 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7743 },
7744 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7745 .vendor_id = QCA_NL80211_VENDOR_ID,
7746 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7747 },
7748 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7749 .vendor_id = QCA_NL80211_VENDOR_ID,
7750 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7751 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307752#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307753/*EXT TDLS*/
7754 {
7755 .vendor_id = QCA_NL80211_VENDOR_ID,
7756 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7757 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307758 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7759 .vendor_id = QCA_NL80211_VENDOR_ID,
7760 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7761 },
7762
Srinivas Dasari030bad32015-02-18 23:23:54 +05307763
7764 {
7765 .vendor_id = QCA_NL80211_VENDOR_ID,
7766 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7767 },
7768
Sushant Kaushik084f6592015-09-10 13:11:56 +05307769 {
7770 .vendor_id = QCA_NL80211_VENDOR_ID,
7771 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307772 },
7773 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7774 .vendor_id = QCA_NL80211_VENDOR_ID,
7775 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7776 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05307777 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
7778 .vendor_id = QCA_NL80211_VENDOR_ID,
7779 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
7780 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307781
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007782};
7783
Jeff Johnson295189b2012-06-20 16:38:30 -07007784/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307785 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307786 * This function is called by hdd_wlan_startup()
7787 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307788 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007789 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307790struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007791{
7792 struct wiphy *wiphy;
7793 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307794 /*
7795 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007796 */
7797 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7798
7799 if (!wiphy)
7800 {
7801 /* Print error and jump into err label and free the memory */
7802 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7803 return NULL;
7804 }
7805
Sunil Duttc69bccb2014-05-26 21:30:20 +05307806
Jeff Johnson295189b2012-06-20 16:38:30 -07007807 return wiphy;
7808}
7809
7810/*
7811 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307812 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007813 * private ioctl to change the band value
7814 */
7815int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7816{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307817 int i, j;
7818 eNVChannelEnabledType channelEnabledState;
7819
Jeff Johnsone7245742012-09-05 17:12:55 -07007820 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307821
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307822 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007823 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307824
7825 if (NULL == wiphy->bands[i])
7826 {
7827 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7828 __func__, i);
7829 continue;
7830 }
7831
7832 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7833 {
7834 struct ieee80211_supported_band *band = wiphy->bands[i];
7835
7836 channelEnabledState = vos_nv_getChannelEnabledState(
7837 band->channels[j].hw_value);
7838
7839 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7840 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307841 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307842 continue;
7843 }
7844 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7845 {
7846 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7847 continue;
7848 }
7849
7850 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7851 NV_CHANNEL_INVALID == channelEnabledState)
7852 {
7853 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7854 }
7855 else if (NV_CHANNEL_DFS == channelEnabledState)
7856 {
7857 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7858 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7859 }
7860 else
7861 {
7862 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7863 |IEEE80211_CHAN_RADAR);
7864 }
7865 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007866 }
7867 return 0;
7868}
7869/*
7870 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307871 * This function is called by hdd_wlan_startup()
7872 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007873 * This function is used to initialize and register wiphy structure.
7874 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307875int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007876 struct wiphy *wiphy,
7877 hdd_config_t *pCfg
7878 )
7879{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307880 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307881 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7882
Jeff Johnsone7245742012-09-05 17:12:55 -07007883 ENTER();
7884
Jeff Johnson295189b2012-06-20 16:38:30 -07007885 /* Now bind the underlying wlan device with wiphy */
7886 set_wiphy_dev(wiphy, dev);
7887
7888 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007889
Kiet Lam6c583332013-10-14 05:37:09 +05307890#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007891 /* the flag for the other case would be initialzed in
7892 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07007893 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307894#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007895
Amar Singhalfddc28c2013-09-05 13:03:40 -07007896 /* This will disable updating of NL channels from passive to
7897 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307898#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7899 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7900#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007901 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307902#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007903
Amar Singhala49cbc52013-10-08 18:37:44 -07007904
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007905#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007906 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7907 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7908 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007909 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307910#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7911 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
7912#else
7913 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7914#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007915#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007916
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007917#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007918 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007919#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007920 || pCfg->isFastRoamIniFeatureEnabled
7921#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007922#ifdef FEATURE_WLAN_ESE
7923 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007924#endif
7925 )
7926 {
7927 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7928 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007929#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007930#ifdef FEATURE_WLAN_TDLS
7931 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7932 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7933#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307934#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307935 if (pCfg->configPNOScanSupport)
7936 {
7937 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7938 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7939 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7940 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7941 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307942#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007943
Abhishek Singh10d85972015-04-17 10:27:23 +05307944#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7945 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7946#endif
7947
Amar Singhalfddc28c2013-09-05 13:03:40 -07007948#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007949 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
7950 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07007951 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007952 driver need to determine what to do with both
7953 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07007954
7955 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07007956#else
7957 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007958#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007959
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307960 wiphy->max_scan_ssids = MAX_SCAN_SSID;
7961
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05307962 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07007963
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307964 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
7965
Jeff Johnson295189b2012-06-20 16:38:30 -07007966 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05307967 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
7968 | BIT(NL80211_IFTYPE_ADHOC)
7969 | BIT(NL80211_IFTYPE_P2P_CLIENT)
7970 | BIT(NL80211_IFTYPE_P2P_GO)
7971 | BIT(NL80211_IFTYPE_AP);
7972
7973 if (VOS_MONITOR_MODE == hdd_get_conparam())
7974 {
7975 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
7976 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007977
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307978 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007979 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307980#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7981 if( pCfg->enableMCC )
7982 {
7983 /* Currently, supports up to two channels */
7984 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007985
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307986 if( !pCfg->allowMCCGODiffBI )
7987 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007988
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307989 }
7990 wiphy->iface_combinations = &wlan_hdd_iface_combination;
7991 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007992#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307993 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007994
Jeff Johnson295189b2012-06-20 16:38:30 -07007995 /* Before registering we need to update the ht capabilitied based
7996 * on ini values*/
7997 if( !pCfg->ShortGI20MhzEnable )
7998 {
7999 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8000 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008001 }
8002
8003 if( !pCfg->ShortGI40MhzEnable )
8004 {
8005 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8006 }
8007
8008 if( !pCfg->nChannelBondingMode5GHz )
8009 {
8010 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8011 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308012 /*
8013 * In case of static linked driver at the time of driver unload,
8014 * module exit doesn't happens. Module cleanup helps in cleaning
8015 * of static memory.
8016 * If driver load happens statically, at the time of driver unload,
8017 * wiphy flags don't get reset because of static memory.
8018 * It's better not to store channel in static memory.
8019 */
8020 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8021 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8022 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8023 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8024 {
8025 hddLog(VOS_TRACE_LEVEL_ERROR,
8026 FL("Not enough memory to allocate channels"));
8027 return -ENOMEM;
8028 }
8029 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8030 &hdd_channels_2_4_GHZ[0],
8031 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008032
Agrawal Ashish97dec502015-11-26 20:20:58 +05308033 if (true == hdd_is_5g_supported(pHddCtx))
8034 {
8035 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8036 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8037 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8038 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8039 {
8040 hddLog(VOS_TRACE_LEVEL_ERROR,
8041 FL("Not enough memory to allocate channels"));
8042 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8043 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8044 return -ENOMEM;
8045 }
8046 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8047 &hdd_channels_5_GHZ[0],
8048 sizeof(hdd_channels_5_GHZ));
8049 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308050
8051 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8052 {
8053
8054 if (NULL == wiphy->bands[i])
8055 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308056 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308057 __func__, i);
8058 continue;
8059 }
8060
8061 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8062 {
8063 struct ieee80211_supported_band *band = wiphy->bands[i];
8064
8065 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8066 {
8067 // Enable social channels for P2P
8068 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8069 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8070 else
8071 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8072 continue;
8073 }
8074 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8075 {
8076 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8077 continue;
8078 }
8079 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008080 }
8081 /*Initialise the supported cipher suite details*/
8082 wiphy->cipher_suites = hdd_cipher_suites;
8083 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8084
8085 /*signal strength in mBm (100*dBm) */
8086 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8087
8088#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308089 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008090#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008091
Sunil Duttc69bccb2014-05-26 21:30:20 +05308092 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8093 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008094 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8095 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8096
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308097 EXIT();
8098 return 0;
8099}
8100
8101/* In this function we are registering wiphy. */
8102int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8103{
8104 ENTER();
8105 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008106 if (0 > wiphy_register(wiphy))
8107 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308108 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008109 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8110 return -EIO;
8111 }
8112
8113 EXIT();
8114 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308115}
Jeff Johnson295189b2012-06-20 16:38:30 -07008116
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308117/* In this function we are updating channel list when,
8118 regulatory domain is FCC and country code is US.
8119 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8120 As per FCC smart phone is not a indoor device.
8121 GO should not opeate on indoor channels */
8122void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8123{
8124 int j;
8125 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8126 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8127 //Default counrtycode from NV at the time of wiphy initialization.
8128 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8129 &defaultCountryCode[0]))
8130 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008131 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308132 }
8133 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8134 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308135 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8136 {
8137 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8138 return;
8139 }
8140 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8141 {
8142 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8143 // Mark UNII -1 band channel as passive
8144 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8145 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8146 }
8147 }
8148}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308149/* This function registers for all frame which supplicant is interested in */
8150void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008151{
Jeff Johnson295189b2012-06-20 16:38:30 -07008152 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8153 /* Register for all P2P action, public action etc frames */
8154 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008155 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308156 /* Register frame indication call back */
8157 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008158 /* Right now we are registering these frame when driver is getting
8159 initialized. Once we will move to 2.6.37 kernel, in which we have
8160 frame register ops, we will move this code as a part of that */
8161 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308162 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008163 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8164
8165 /* GAS Initial Response */
8166 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8167 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308168
Jeff Johnson295189b2012-06-20 16:38:30 -07008169 /* GAS Comeback Request */
8170 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8171 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8172
8173 /* GAS Comeback Response */
8174 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8175 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8176
8177 /* P2P Public Action */
8178 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308179 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008180 P2P_PUBLIC_ACTION_FRAME_SIZE );
8181
8182 /* P2P Action */
8183 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8184 (v_U8_t*)P2P_ACTION_FRAME,
8185 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008186
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308187 /* WNM BSS Transition Request frame */
8188 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8189 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8190 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008191
8192 /* WNM-Notification */
8193 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8194 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8195 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008196}
8197
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308198void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008199{
Jeff Johnson295189b2012-06-20 16:38:30 -07008200 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8201 /* Register for all P2P action, public action etc frames */
8202 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8203
Jeff Johnsone7245742012-09-05 17:12:55 -07008204 ENTER();
8205
Jeff Johnson295189b2012-06-20 16:38:30 -07008206 /* Right now we are registering these frame when driver is getting
8207 initialized. Once we will move to 2.6.37 kernel, in which we have
8208 frame register ops, we will move this code as a part of that */
8209 /* GAS Initial Request */
8210
8211 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8212 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8213
8214 /* GAS Initial Response */
8215 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8216 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308217
Jeff Johnson295189b2012-06-20 16:38:30 -07008218 /* GAS Comeback Request */
8219 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8220 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8221
8222 /* GAS Comeback Response */
8223 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8224 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8225
8226 /* P2P Public Action */
8227 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308228 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008229 P2P_PUBLIC_ACTION_FRAME_SIZE );
8230
8231 /* P2P Action */
8232 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8233 (v_U8_t*)P2P_ACTION_FRAME,
8234 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008235 /* WNM-Notification */
8236 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8237 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8238 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008239}
8240
8241#ifdef FEATURE_WLAN_WAPI
8242void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308243 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008244{
8245 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8246 tCsrRoamSetKey setKey;
8247 v_BOOL_t isConnected = TRUE;
8248 int status = 0;
8249 v_U32_t roamId= 0xFF;
8250 tANI_U8 *pKeyPtr = NULL;
8251 int n = 0;
8252
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308253 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8254 __func__, hdd_device_modetoString(pAdapter->device_mode),
8255 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008256
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308257 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008258 setKey.keyId = key_index; // Store Key ID
8259 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8260 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8261 setKey.paeRole = 0 ; // the PAE role
8262 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8263 {
8264 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8265 }
8266 else
8267 {
8268 isConnected = hdd_connIsConnected(pHddStaCtx);
8269 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8270 }
8271 setKey.keyLength = key_Len;
8272 pKeyPtr = setKey.Key;
8273 memcpy( pKeyPtr, key, key_Len);
8274
Arif Hussain6d2a3322013-11-17 19:50:10 -08008275 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008276 __func__, key_Len);
8277 for (n = 0 ; n < key_Len; n++)
8278 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8279 __func__,n,setKey.Key[n]);
8280
8281 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8282 if ( isConnected )
8283 {
8284 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8285 pAdapter->sessionId, &setKey, &roamId );
8286 }
8287 if ( status != 0 )
8288 {
8289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8290 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8291 __LINE__, status );
8292 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8293 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308294 /* Need to clear any trace of key value in the memory.
8295 * Thus zero out the memory even though it is local
8296 * variable.
8297 */
8298 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008299}
8300#endif /* FEATURE_WLAN_WAPI*/
8301
8302#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308303int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008304 beacon_data_t **ppBeacon,
8305 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008306#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308307int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008308 beacon_data_t **ppBeacon,
8309 struct cfg80211_beacon_data *params,
8310 int dtim_period)
8311#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308312{
Jeff Johnson295189b2012-06-20 16:38:30 -07008313 int size;
8314 beacon_data_t *beacon = NULL;
8315 beacon_data_t *old = NULL;
8316 int head_len,tail_len;
8317
Jeff Johnsone7245742012-09-05 17:12:55 -07008318 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008319 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308320 {
8321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8322 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008323 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308324 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008325
8326 old = pAdapter->sessionCtx.ap.beacon;
8327
8328 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308329 {
8330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8331 FL("session(%d) old and new heads points to NULL"),
8332 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008333 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308334 }
8335
8336 if (params->tail && !params->tail_len)
8337 {
8338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8339 FL("tail_len is zero but tail is not NULL"));
8340 return -EINVAL;
8341 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008342
Jeff Johnson295189b2012-06-20 16:38:30 -07008343#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8344 /* Kernel 3.0 is not updating dtim_period for set beacon */
8345 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308346 {
8347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8348 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008349 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308350 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008351#endif
8352
8353 if(params->head)
8354 head_len = params->head_len;
8355 else
8356 head_len = old->head_len;
8357
8358 if(params->tail || !old)
8359 tail_len = params->tail_len;
8360 else
8361 tail_len = old->tail_len;
8362
8363 size = sizeof(beacon_data_t) + head_len + tail_len;
8364
8365 beacon = kzalloc(size, GFP_KERNEL);
8366
8367 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308368 {
8369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8370 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008371 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308372 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008373
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008374#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008375 if(params->dtim_period || !old )
8376 beacon->dtim_period = params->dtim_period;
8377 else
8378 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008379#else
8380 if(dtim_period || !old )
8381 beacon->dtim_period = dtim_period;
8382 else
8383 beacon->dtim_period = old->dtim_period;
8384#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308385
Jeff Johnson295189b2012-06-20 16:38:30 -07008386 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8387 beacon->tail = beacon->head + head_len;
8388 beacon->head_len = head_len;
8389 beacon->tail_len = tail_len;
8390
8391 if(params->head) {
8392 memcpy (beacon->head,params->head,beacon->head_len);
8393 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308394 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07008395 if(old)
8396 memcpy (beacon->head,old->head,beacon->head_len);
8397 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308398
Jeff Johnson295189b2012-06-20 16:38:30 -07008399 if(params->tail) {
8400 memcpy (beacon->tail,params->tail,beacon->tail_len);
8401 }
8402 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308403 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07008404 memcpy (beacon->tail,old->tail,beacon->tail_len);
8405 }
8406
8407 *ppBeacon = beacon;
8408
8409 kfree(old);
8410
8411 return 0;
8412
8413}
Jeff Johnson295189b2012-06-20 16:38:30 -07008414
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308415v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8416#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8417 const v_U8_t *pIes,
8418#else
8419 v_U8_t *pIes,
8420#endif
8421 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008422{
8423 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308424 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008425 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308426
Jeff Johnson295189b2012-06-20 16:38:30 -07008427 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308428 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008429 elem_id = ptr[0];
8430 elem_len = ptr[1];
8431 left -= 2;
8432 if(elem_len > left)
8433 {
8434 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008435 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008436 eid,elem_len,left);
8437 return NULL;
8438 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308439 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 {
8441 return ptr;
8442 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308443
Jeff Johnson295189b2012-06-20 16:38:30 -07008444 left -= elem_len;
8445 ptr += (elem_len + 2);
8446 }
8447 return NULL;
8448}
8449
Jeff Johnson295189b2012-06-20 16:38:30 -07008450/* Check if rate is 11g rate or not */
8451static int wlan_hdd_rate_is_11g(u8 rate)
8452{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008453 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008454 u8 i;
8455 for (i = 0; i < 8; i++)
8456 {
8457 if(rate == gRateArray[i])
8458 return TRUE;
8459 }
8460 return FALSE;
8461}
8462
8463/* Check for 11g rate and set proper 11g only mode */
8464static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8465 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8466{
8467 u8 i, num_rates = pIe[0];
8468
8469 pIe += 1;
8470 for ( i = 0; i < num_rates; i++)
8471 {
8472 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8473 {
8474 /* If rate set have 11g rate than change the mode to 11G */
8475 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8476 if (pIe[i] & BASIC_RATE_MASK)
8477 {
8478 /* If we have 11g rate as basic rate, it means mode
8479 is 11g only mode.
8480 */
8481 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8482 *pCheckRatesfor11g = FALSE;
8483 }
8484 }
8485 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8486 {
8487 *require_ht = TRUE;
8488 }
8489 }
8490 return;
8491}
8492
8493static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8494{
8495 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8496 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8497 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8498 u8 checkRatesfor11g = TRUE;
8499 u8 require_ht = FALSE;
8500 u8 *pIe=NULL;
8501
8502 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8503
8504 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8505 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8506 if (pIe != NULL)
8507 {
8508 pIe += 1;
8509 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8510 &pConfig->SapHw_mode);
8511 }
8512
8513 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8514 WLAN_EID_EXT_SUPP_RATES);
8515 if (pIe != NULL)
8516 {
8517
8518 pIe += 1;
8519 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8520 &pConfig->SapHw_mode);
8521 }
8522
8523 if( pConfig->channel > 14 )
8524 {
8525 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8526 }
8527
8528 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8529 WLAN_EID_HT_CAPABILITY);
8530
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308531 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008532 {
8533 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8534 if(require_ht)
8535 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8536 }
8537}
8538
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308539static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8540 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8541{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008542 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308543 v_U8_t *pIe = NULL;
8544 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8545
8546 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8547 pBeacon->tail, pBeacon->tail_len);
8548
8549 if (pIe)
8550 {
8551 ielen = pIe[1] + 2;
8552 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8553 {
8554 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8555 }
8556 else
8557 {
8558 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8559 return -EINVAL;
8560 }
8561 *total_ielen += ielen;
8562 }
8563 return 0;
8564}
8565
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008566static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8567 v_U8_t *genie, v_U8_t *total_ielen)
8568{
8569 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8570 int left = pBeacon->tail_len;
8571 v_U8_t *ptr = pBeacon->tail;
8572 v_U8_t elem_id, elem_len;
8573 v_U16_t ielen = 0;
8574
8575 if ( NULL == ptr || 0 == left )
8576 return;
8577
8578 while (left >= 2)
8579 {
8580 elem_id = ptr[0];
8581 elem_len = ptr[1];
8582 left -= 2;
8583 if (elem_len > left)
8584 {
8585 hddLog( VOS_TRACE_LEVEL_ERROR,
8586 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8587 elem_id, elem_len, left);
8588 return;
8589 }
8590 if (IE_EID_VENDOR == elem_id)
8591 {
8592 /* skipping the VSIE's which we don't want to include or
8593 * it will be included by existing code
8594 */
8595 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8596#ifdef WLAN_FEATURE_WFD
8597 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8598#endif
8599 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8600 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8601 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8602 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8603 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8604 {
8605 ielen = ptr[1] + 2;
8606 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8607 {
8608 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8609 *total_ielen += ielen;
8610 }
8611 else
8612 {
8613 hddLog( VOS_TRACE_LEVEL_ERROR,
8614 "IE Length is too big "
8615 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8616 elem_id, elem_len, *total_ielen);
8617 }
8618 }
8619 }
8620
8621 left -= elem_len;
8622 ptr += (elem_len + 2);
8623 }
8624 return;
8625}
8626
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008627#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008628static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8629 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008630#else
8631static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8632 struct cfg80211_beacon_data *params)
8633#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008634{
8635 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308636 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008637 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008638 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008639
8640 genie = vos_mem_malloc(MAX_GENIE_LEN);
8641
8642 if(genie == NULL) {
8643
8644 return -ENOMEM;
8645 }
8646
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308647 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8648 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008649 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308650 hddLog(LOGE,
8651 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308652 ret = -EINVAL;
8653 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008654 }
8655
8656#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308657 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8658 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8659 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308660 hddLog(LOGE,
8661 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308662 ret = -EINVAL;
8663 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008664 }
8665#endif
8666
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308667 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8668 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008669 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308670 hddLog(LOGE,
8671 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308672 ret = -EINVAL;
8673 goto done;
8674 }
8675
8676 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8677 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008678 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008679 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008680
8681 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8682 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8683 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8684 {
8685 hddLog(LOGE,
8686 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008687 ret = -EINVAL;
8688 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008689 }
8690
8691 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8692 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8693 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8694 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8695 ==eHAL_STATUS_FAILURE)
8696 {
8697 hddLog(LOGE,
8698 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008699 ret = -EINVAL;
8700 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008701 }
8702
8703 // Added for ProResp IE
8704 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
8705 {
8706 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
8707 u8 probe_rsp_ie_len[3] = {0};
8708 u8 counter = 0;
8709 /* Check Probe Resp Length if it is greater then 255 then Store
8710 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8711 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8712 Store More then 255 bytes into One Variable.
8713 */
8714 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8715 {
8716 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8717 {
8718 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8719 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8720 }
8721 else
8722 {
8723 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8724 rem_probe_resp_ie_len = 0;
8725 }
8726 }
8727
8728 rem_probe_resp_ie_len = 0;
8729
8730 if (probe_rsp_ie_len[0] > 0)
8731 {
8732 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8733 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
8734 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8735 probe_rsp_ie_len[0], NULL,
8736 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8737 {
8738 hddLog(LOGE,
8739 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008740 ret = -EINVAL;
8741 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008742 }
8743 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8744 }
8745
8746 if (probe_rsp_ie_len[1] > 0)
8747 {
8748 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8749 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
8750 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8751 probe_rsp_ie_len[1], NULL,
8752 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8753 {
8754 hddLog(LOGE,
8755 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008756 ret = -EINVAL;
8757 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008758 }
8759 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8760 }
8761
8762 if (probe_rsp_ie_len[2] > 0)
8763 {
8764 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8765 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
8766 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8767 probe_rsp_ie_len[2], NULL,
8768 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8769 {
8770 hddLog(LOGE,
8771 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008772 ret = -EINVAL;
8773 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008774 }
8775 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8776 }
8777
8778 if (probe_rsp_ie_len[1] == 0 )
8779 {
8780 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8781 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8782 eANI_BOOLEAN_FALSE) )
8783 {
8784 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008785 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 }
8787 }
8788
8789 if (probe_rsp_ie_len[2] == 0 )
8790 {
8791 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8792 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8793 eANI_BOOLEAN_FALSE) )
8794 {
8795 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008796 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008797 }
8798 }
8799
8800 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8801 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8802 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8803 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8804 == eHAL_STATUS_FAILURE)
8805 {
8806 hddLog(LOGE,
8807 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008808 ret = -EINVAL;
8809 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008810 }
8811 }
8812 else
8813 {
8814 // Reset WNI_CFG_PROBE_RSP Flags
8815 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8816
8817 hddLog(VOS_TRACE_LEVEL_INFO,
8818 "%s: No Probe Response IE received in set beacon",
8819 __func__);
8820 }
8821
8822 // Added for AssocResp IE
8823 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
8824 {
8825 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8826 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
8827 params->assocresp_ies_len, NULL,
8828 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8829 {
8830 hddLog(LOGE,
8831 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008832 ret = -EINVAL;
8833 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008834 }
8835
8836 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8837 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8838 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8839 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8840 == eHAL_STATUS_FAILURE)
8841 {
8842 hddLog(LOGE,
8843 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008844 ret = -EINVAL;
8845 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008846 }
8847 }
8848 else
8849 {
8850 hddLog(VOS_TRACE_LEVEL_INFO,
8851 "%s: No Assoc Response IE received in set beacon",
8852 __func__);
8853
8854 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8855 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8856 eANI_BOOLEAN_FALSE) )
8857 {
8858 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008859 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008860 }
8861 }
8862
Jeff Johnsone7245742012-09-05 17:12:55 -07008863done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008864 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308865 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008866}
Jeff Johnson295189b2012-06-20 16:38:30 -07008867
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308868/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008869 * FUNCTION: wlan_hdd_validate_operation_channel
8870 * called by wlan_hdd_cfg80211_start_bss() and
8871 * wlan_hdd_cfg80211_set_channel()
8872 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308873 * channel list.
8874 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008875VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008876{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308877
Jeff Johnson295189b2012-06-20 16:38:30 -07008878 v_U32_t num_ch = 0;
8879 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8880 u32 indx = 0;
8881 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308882 v_U8_t fValidChannel = FALSE, count = 0;
8883 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308884
Jeff Johnson295189b2012-06-20 16:38:30 -07008885 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8886
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308887 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008888 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308889 /* Validate the channel */
8890 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008891 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308892 if ( channel == rfChannels[count].channelNum )
8893 {
8894 fValidChannel = TRUE;
8895 break;
8896 }
8897 }
8898 if (fValidChannel != TRUE)
8899 {
8900 hddLog(VOS_TRACE_LEVEL_ERROR,
8901 "%s: Invalid Channel [%d]", __func__, channel);
8902 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008903 }
8904 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308905 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008906 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308907 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8908 valid_ch, &num_ch))
8909 {
8910 hddLog(VOS_TRACE_LEVEL_ERROR,
8911 "%s: failed to get valid channel list", __func__);
8912 return VOS_STATUS_E_FAILURE;
8913 }
8914 for (indx = 0; indx < num_ch; indx++)
8915 {
8916 if (channel == valid_ch[indx])
8917 {
8918 break;
8919 }
8920 }
8921
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308922 if (indx >= num_ch)
8923 {
8924 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8925 {
8926 eCsrBand band;
8927 unsigned int freq;
8928
8929 sme_GetFreqBand(hHal, &band);
8930
8931 if (eCSR_BAND_5G == band)
8932 {
8933#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8934 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8935 {
8936 freq = ieee80211_channel_to_frequency(channel,
8937 IEEE80211_BAND_2GHZ);
8938 }
8939 else
8940 {
8941 freq = ieee80211_channel_to_frequency(channel,
8942 IEEE80211_BAND_5GHZ);
8943 }
8944#else
8945 freq = ieee80211_channel_to_frequency(channel);
8946#endif
8947 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
8948 return VOS_STATUS_SUCCESS;
8949 }
8950 }
8951
8952 hddLog(VOS_TRACE_LEVEL_ERROR,
8953 "%s: Invalid Channel [%d]", __func__, channel);
8954 return VOS_STATUS_E_FAILURE;
8955 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008956 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308957
Jeff Johnson295189b2012-06-20 16:38:30 -07008958 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308959
Jeff Johnson295189b2012-06-20 16:38:30 -07008960}
8961
Viral Modi3a32cc52013-02-08 11:14:52 -08008962/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308963 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08008964 * This function is used to set the channel number
8965 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308966static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08008967 struct ieee80211_channel *chan,
8968 enum nl80211_channel_type channel_type
8969 )
8970{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308971 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08008972 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07008973 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08008974 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308975 hdd_context_t *pHddCtx;
8976 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008977
8978 ENTER();
8979
8980 if( NULL == dev )
8981 {
8982 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008983 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08008984 return -ENODEV;
8985 }
8986 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308987
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308988 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8989 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
8990 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08008991 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308992 "%s: device_mode = %s (%d) freq = %d", __func__,
8993 hdd_device_modetoString(pAdapter->device_mode),
8994 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308995
8996 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8997 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308998 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08008999 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309000 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009001 }
9002
9003 /*
9004 * Do freq to chan conversion
9005 * TODO: for 11a
9006 */
9007
9008 channel = ieee80211_frequency_to_channel(freq);
9009
9010 /* Check freq range */
9011 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9012 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9013 {
9014 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009015 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009016 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9017 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9018 return -EINVAL;
9019 }
9020
9021 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9022
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309023 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9024 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009025 {
9026 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9027 {
9028 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009029 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009030 return -EINVAL;
9031 }
9032 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9033 "%s: set channel to [%d] for device mode =%d",
9034 __func__, channel,pAdapter->device_mode);
9035 }
9036 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009037 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009038 )
9039 {
9040 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9041 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9042 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9043
9044 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9045 {
9046 /* Link is up then return cant set channel*/
9047 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009048 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009049 return -EINVAL;
9050 }
9051
9052 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9053 pHddStaCtx->conn_info.operationChannel = channel;
9054 pRoamProfile->ChannelInfo.ChannelList =
9055 &pHddStaCtx->conn_info.operationChannel;
9056 }
9057 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009058 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009059 )
9060 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309061 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9062 {
9063 if(VOS_STATUS_SUCCESS !=
9064 wlan_hdd_validate_operation_channel(pAdapter,channel))
9065 {
9066 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009067 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309068 return -EINVAL;
9069 }
9070 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9071 }
9072 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009073 {
9074 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9075
9076 /* If auto channel selection is configured as enable/ 1 then ignore
9077 channel set by supplicant
9078 */
9079 if ( cfg_param->apAutoChannelSelection )
9080 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309081 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9082 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009083 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309084 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9085 __func__, hdd_device_modetoString(pAdapter->device_mode),
9086 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009087 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309088 else
9089 {
9090 if(VOS_STATUS_SUCCESS !=
9091 wlan_hdd_validate_operation_channel(pAdapter,channel))
9092 {
9093 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009094 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309095 return -EINVAL;
9096 }
9097 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9098 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009099 }
9100 }
9101 else
9102 {
9103 hddLog(VOS_TRACE_LEVEL_FATAL,
9104 "%s: Invalid device mode failed to set valid channel", __func__);
9105 return -EINVAL;
9106 }
9107 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309108 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009109}
9110
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309111static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9112 struct net_device *dev,
9113 struct ieee80211_channel *chan,
9114 enum nl80211_channel_type channel_type
9115 )
9116{
9117 int ret;
9118
9119 vos_ssr_protect(__func__);
9120 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9121 vos_ssr_unprotect(__func__);
9122
9123 return ret;
9124}
9125
Jeff Johnson295189b2012-06-20 16:38:30 -07009126#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9127static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9128 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009129#else
9130static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9131 struct cfg80211_beacon_data *params,
9132 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309133 enum nl80211_hidden_ssid hidden_ssid,
9134 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009135#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009136{
9137 tsap_Config_t *pConfig;
9138 beacon_data_t *pBeacon = NULL;
9139 struct ieee80211_mgmt *pMgmt_frame;
9140 v_U8_t *pIe=NULL;
9141 v_U16_t capab_info;
9142 eCsrAuthType RSNAuthType;
9143 eCsrEncryptionType RSNEncryptType;
9144 eCsrEncryptionType mcRSNEncryptType;
9145 int status = VOS_STATUS_SUCCESS;
9146 tpWLAN_SAPEventCB pSapEventCallback;
9147 hdd_hostapd_state_t *pHostapdState;
9148 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
9149 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309150 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009151 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309152 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009153 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009154 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309155 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009156 v_BOOL_t MFPCapable = VOS_FALSE;
9157 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309158 v_BOOL_t sapEnable11AC =
9159 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07009160 ENTER();
9161
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309162 iniConfig = pHddCtx->cfg_ini;
9163
Jeff Johnson295189b2012-06-20 16:38:30 -07009164 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9165
9166 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9167
9168 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9169
9170 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9171
9172 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9173
9174 //channel is already set in the set_channel Call back
9175 //pConfig->channel = pCommitConfig->channel;
9176
9177 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309178 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009179 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9180
9181 pConfig->dtim_period = pBeacon->dtim_period;
9182
Arif Hussain6d2a3322013-11-17 19:50:10 -08009183 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009184 pConfig->dtim_period);
9185
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009186 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009187 {
9188 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009189 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309190 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9191 {
9192 tANI_BOOLEAN restartNeeded;
9193 pConfig->ieee80211d = 1;
9194 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9195 sme_setRegInfo(hHal, pConfig->countryCode);
9196 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9197 }
9198 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009199 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009200 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009201 pConfig->ieee80211d = 1;
9202 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9203 sme_setRegInfo(hHal, pConfig->countryCode);
9204 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009205 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009206 else
9207 {
9208 pConfig->ieee80211d = 0;
9209 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309210 /*
9211 * If auto channel is configured i.e. channel is 0,
9212 * so skip channel validation.
9213 */
9214 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9215 {
9216 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9217 {
9218 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009219 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309220 return -EINVAL;
9221 }
9222 }
9223 else
9224 {
9225 if(1 != pHddCtx->is_dynamic_channel_range_set)
9226 {
9227 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9228 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9229 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9230 }
9231 pHddCtx->is_dynamic_channel_range_set = 0;
9232 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009233 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009234 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009235 {
9236 pConfig->ieee80211d = 0;
9237 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309238
9239#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9240 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9241 pConfig->authType = eSAP_OPEN_SYSTEM;
9242 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9243 pConfig->authType = eSAP_SHARED_KEY;
9244 else
9245 pConfig->authType = eSAP_AUTO_SWITCH;
9246#else
9247 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9248 pConfig->authType = eSAP_OPEN_SYSTEM;
9249 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9250 pConfig->authType = eSAP_SHARED_KEY;
9251 else
9252 pConfig->authType = eSAP_AUTO_SWITCH;
9253#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009254
9255 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309256
9257 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009258 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
9259
9260 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9261
9262 /*Set wps station to configured*/
9263 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9264
9265 if(pIe)
9266 {
9267 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9268 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009269 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009270 return -EINVAL;
9271 }
9272 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9273 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009274 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009275 /* Check 15 bit of WPS IE as it contain information for wps state
9276 * WPS state
9277 */
9278 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9279 {
9280 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9281 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9282 {
9283 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9284 }
9285 }
9286 }
9287 else
9288 {
9289 pConfig->wps_state = SAP_WPS_DISABLED;
9290 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309291 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009292
c_hpothufe599e92014-06-16 11:38:55 +05309293 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9294 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9295 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9296 eCSR_ENCRYPT_TYPE_NONE;
9297
Jeff Johnson295189b2012-06-20 16:38:30 -07009298 pConfig->RSNWPAReqIELength = 0;
9299 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309300 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009301 WLAN_EID_RSN);
9302 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309303 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009304 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9305 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9306 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309307 /* The actual processing may eventually be more extensive than
9308 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009309 * by the app.
9310 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309311 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009312 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9313 &RSNEncryptType,
9314 &mcRSNEncryptType,
9315 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009316 &MFPCapable,
9317 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009318 pConfig->pRSNWPAReqIE[1]+2,
9319 pConfig->pRSNWPAReqIE );
9320
9321 if( VOS_STATUS_SUCCESS == status )
9322 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309323 /* Now copy over all the security attributes you have
9324 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009325 * */
9326 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9327 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9328 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9329 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309330 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009331 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009332 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9333 }
9334 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309335
Jeff Johnson295189b2012-06-20 16:38:30 -07009336 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9337 pBeacon->tail, pBeacon->tail_len);
9338
9339 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9340 {
9341 if (pConfig->pRSNWPAReqIE)
9342 {
9343 /*Mixed mode WPA/WPA2*/
9344 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
9345 pConfig->RSNWPAReqIELength += pIe[1] + 2;
9346 }
9347 else
9348 {
9349 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9350 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9351 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309352 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009353 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9354 &RSNEncryptType,
9355 &mcRSNEncryptType,
9356 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009357 &MFPCapable,
9358 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009359 pConfig->pRSNWPAReqIE[1]+2,
9360 pConfig->pRSNWPAReqIE );
9361
9362 if( VOS_STATUS_SUCCESS == status )
9363 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309364 /* Now copy over all the security attributes you have
9365 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009366 * */
9367 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9368 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9369 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9370 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309371 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009372 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009373 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9374 }
9375 }
9376 }
9377
Jeff Johnson4416a782013-03-25 14:17:50 -07009378 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
9379 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9380 return -EINVAL;
9381 }
9382
Jeff Johnson295189b2012-06-20 16:38:30 -07009383 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9384
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009385#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009386 if (params->ssid != NULL)
9387 {
9388 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9389 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9390 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9391 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9392 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009393#else
9394 if (ssid != NULL)
9395 {
9396 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9397 pConfig->SSIDinfo.ssid.length = ssid_len;
9398 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9399 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9400 }
9401#endif
9402
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309403 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009404 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309405
Jeff Johnson295189b2012-06-20 16:38:30 -07009406 /* default value */
9407 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9408 pConfig->num_accept_mac = 0;
9409 pConfig->num_deny_mac = 0;
9410
9411 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9412 pBeacon->tail, pBeacon->tail_len);
9413
9414 /* pIe for black list is following form:
9415 type : 1 byte
9416 length : 1 byte
9417 OUI : 4 bytes
9418 acl type : 1 byte
9419 no of mac addr in black list: 1 byte
9420 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309421 */
9422 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009423 {
9424 pConfig->SapMacaddr_acl = pIe[6];
9425 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009426 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009427 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309428 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9429 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009430 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9431 for (i = 0; i < pConfig->num_deny_mac; i++)
9432 {
9433 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9434 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309435 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009436 }
9437 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9438 pBeacon->tail, pBeacon->tail_len);
9439
9440 /* pIe for white list is following form:
9441 type : 1 byte
9442 length : 1 byte
9443 OUI : 4 bytes
9444 acl type : 1 byte
9445 no of mac addr in white list: 1 byte
9446 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309447 */
9448 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009449 {
9450 pConfig->SapMacaddr_acl = pIe[6];
9451 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009452 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009453 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309454 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9455 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009456 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9457 for (i = 0; i < pConfig->num_accept_mac; i++)
9458 {
9459 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9460 acl_entry++;
9461 }
9462 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309463
Jeff Johnson295189b2012-06-20 16:38:30 -07009464 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9465
Jeff Johnsone7245742012-09-05 17:12:55 -07009466#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009467 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309468 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9469 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309470 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9471 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009472 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9473 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309474 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9475 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009476 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309477 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009478 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309479 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009480
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309481 /* If ACS disable and selected channel <= 14
9482 * OR
9483 * ACS enabled and ACS operating band is choosen as 2.4
9484 * AND
9485 * VHT in 2.4G Disabled
9486 * THEN
9487 * Fallback to 11N mode
9488 */
9489 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9490 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309491 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309492 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009493 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309494 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9495 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009496 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9497 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009498 }
9499#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309500
Jeff Johnson295189b2012-06-20 16:38:30 -07009501 // ht_capab is not what the name conveys,this is used for protection bitmap
9502 pConfig->ht_capab =
9503 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9504
9505 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
9506 {
9507 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9508 return -EINVAL;
9509 }
9510
9511 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309512 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009513 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9514 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309515 pConfig->obssProtEnabled =
9516 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009517
Chet Lanctot8cecea22014-02-11 19:09:36 -08009518#ifdef WLAN_FEATURE_11W
9519 pConfig->mfpCapable = MFPCapable;
9520 pConfig->mfpRequired = MFPRequired;
9521 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9522 pConfig->mfpCapable, pConfig->mfpRequired);
9523#endif
9524
Arif Hussain6d2a3322013-11-17 19:50:10 -08009525 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009526 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009527 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9528 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9529 (int)pConfig->channel);
9530 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9531 pConfig->SapHw_mode, pConfig->privacy,
9532 pConfig->authType);
9533 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9534 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9535 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9536 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009537
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309538 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009539 {
9540 //Bss already started. just return.
9541 //TODO Probably it should update some beacon params.
9542 hddLog( LOGE, "Bss Already started...Ignore the request");
9543 EXIT();
9544 return 0;
9545 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309546
Agarwal Ashish51325b52014-06-16 16:50:49 +05309547 if (vos_max_concurrent_connections_reached()) {
9548 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9549 return -EINVAL;
9550 }
9551
Jeff Johnson295189b2012-06-20 16:38:30 -07009552 pConfig->persona = pHostapdAdapter->device_mode;
9553
Peng Xu2446a892014-09-05 17:21:18 +05309554 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9555 if ( NULL != psmeConfig)
9556 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309557 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309558 sme_GetConfigParam(hHal, psmeConfig);
9559 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309560#ifdef WLAN_FEATURE_AP_HT40_24G
9561 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9562 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9563 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9564 {
9565 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9566 sme_UpdateConfig (hHal, psmeConfig);
9567 }
9568#endif
Peng Xu2446a892014-09-05 17:21:18 +05309569 vos_mem_free(psmeConfig);
9570 }
Peng Xuafc34e32014-09-25 13:23:55 +05309571 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309572
Jeff Johnson295189b2012-06-20 16:38:30 -07009573 pSapEventCallback = hdd_hostapd_SAPEventCB;
9574 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9575 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9576 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009577 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009578 return -EINVAL;
9579 }
9580
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309581 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009582 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9583
9584 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309585
Jeff Johnson295189b2012-06-20 16:38:30 -07009586 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309587 {
9588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009589 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009590 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009591 VOS_ASSERT(0);
9592 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309593
Jeff Johnson295189b2012-06-20 16:38:30 -07009594 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309595 /* Initialize WMM configuation */
9596 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309597 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009598
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009599#ifdef WLAN_FEATURE_P2P_DEBUG
9600 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9601 {
9602 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9603 {
9604 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9605 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009606 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009607 }
9608 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9609 {
9610 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9611 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009612 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009613 }
9614 }
9615#endif
9616
Jeff Johnson295189b2012-06-20 16:38:30 -07009617 pHostapdState->bCommit = TRUE;
9618 EXIT();
9619
9620 return 0;
9621}
9622
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009623#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309624static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309625 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009626 struct beacon_parameters *params)
9627{
9628 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309629 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309630 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009631
9632 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309633
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309634 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9635 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9636 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309637 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9638 hdd_device_modetoString(pAdapter->device_mode),
9639 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009640
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309641 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9642 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309643 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009644 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309645 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009646 }
9647
Agarwal Ashish51325b52014-06-16 16:50:49 +05309648 if (vos_max_concurrent_connections_reached()) {
9649 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9650 return -EINVAL;
9651 }
9652
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309653 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009654 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009655 )
9656 {
9657 beacon_data_t *old,*new;
9658
9659 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309660
Jeff Johnson295189b2012-06-20 16:38:30 -07009661 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309662 {
9663 hddLog(VOS_TRACE_LEVEL_WARN,
9664 FL("already beacon info added to session(%d)"),
9665 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009666 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309667 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009668
9669 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9670
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309671 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009672 {
9673 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009674 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 return -EINVAL;
9676 }
9677
9678 pAdapter->sessionCtx.ap.beacon = new;
9679
9680 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9681 }
9682
9683 EXIT();
9684 return status;
9685}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309686
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309687static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9688 struct net_device *dev,
9689 struct beacon_parameters *params)
9690{
9691 int ret;
9692
9693 vos_ssr_protect(__func__);
9694 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
9695 vos_ssr_unprotect(__func__);
9696
9697 return ret;
9698}
9699
9700static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 struct net_device *dev,
9702 struct beacon_parameters *params)
9703{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309704 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309705 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9706 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309707 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009708
9709 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309710
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309711 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9712 TRACE_CODE_HDD_CFG80211_SET_BEACON,
9713 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
9714 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9715 __func__, hdd_device_modetoString(pAdapter->device_mode),
9716 pAdapter->device_mode);
9717
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309718 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9719 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309720 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009721 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309722 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009723 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309724
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309725 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009726 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309727 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009728 {
9729 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309730
Jeff Johnson295189b2012-06-20 16:38:30 -07009731 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309732
Jeff Johnson295189b2012-06-20 16:38:30 -07009733 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309734 {
9735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9736 FL("session(%d) old and new heads points to NULL"),
9737 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009738 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309739 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009740
9741 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9742
9743 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309744 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009745 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009746 return -EINVAL;
9747 }
9748
9749 pAdapter->sessionCtx.ap.beacon = new;
9750
9751 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9752 }
9753
9754 EXIT();
9755 return status;
9756}
9757
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309758static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
9759 struct net_device *dev,
9760 struct beacon_parameters *params)
9761{
9762 int ret;
9763
9764 vos_ssr_protect(__func__);
9765 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
9766 vos_ssr_unprotect(__func__);
9767
9768 return ret;
9769}
9770
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009771#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9772
9773#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309774static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009775 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009776#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309777static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009778 struct net_device *dev)
9779#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009780{
9781 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07009782 hdd_context_t *pHddCtx = NULL;
9783 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309784 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309785 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009786
9787 ENTER();
9788
9789 if (NULL == pAdapter)
9790 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009792 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009793 return -ENODEV;
9794 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009795
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309796 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9797 TRACE_CODE_HDD_CFG80211_STOP_AP,
9798 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309799 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9800 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309801 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009802 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309803 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07009804 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009805
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009806 pScanInfo = &pHddCtx->scan_info;
9807
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309808 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9809 __func__, hdd_device_modetoString(pAdapter->device_mode),
9810 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009811
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309812 ret = wlan_hdd_scan_abort(pAdapter);
9813
Girish Gowli4bf7a632014-06-12 13:42:11 +05309814 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07009815 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9817 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309818
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309819 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07009820 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9822 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08009823
Jeff Johnsone7245742012-09-05 17:12:55 -07009824 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309825 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07009826 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309827 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009828 }
9829
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05309830 /* Delete all associated STAs before stopping AP/P2P GO */
9831 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05309832 hdd_hostapd_stop(dev);
9833
Jeff Johnson295189b2012-06-20 16:38:30 -07009834 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009835 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009836 )
9837 {
9838 beacon_data_t *old;
9839
9840 old = pAdapter->sessionCtx.ap.beacon;
9841
9842 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309843 {
9844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9845 FL("session(%d) beacon data points to NULL"),
9846 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309848 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009849
Jeff Johnson295189b2012-06-20 16:38:30 -07009850 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009851
9852 mutex_lock(&pHddCtx->sap_lock);
9853 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9854 {
Jeff Johnson4416a782013-03-25 14:17:50 -07009855 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009856 {
9857 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9858
9859 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9860
9861 if (!VOS_IS_STATUS_SUCCESS(status))
9862 {
9863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009864 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009865 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309866 }
9867 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009868 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309869 /* BSS stopped, clear the active sessions for this device mode */
9870 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 }
9872 mutex_unlock(&pHddCtx->sap_lock);
9873
9874 if(status != VOS_STATUS_SUCCESS)
9875 {
9876 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009877 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009878 return -EINVAL;
9879 }
9880
Jeff Johnson4416a782013-03-25 14:17:50 -07009881 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009882 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
9883 ==eHAL_STATUS_FAILURE)
9884 {
9885 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009886 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009887 }
9888
Jeff Johnson4416a782013-03-25 14:17:50 -07009889 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009890 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9891 eANI_BOOLEAN_FALSE) )
9892 {
9893 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009894 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009895 }
9896
9897 // Reset WNI_CFG_PROBE_RSP Flags
9898 wlan_hdd_reset_prob_rspies(pAdapter);
9899
9900 pAdapter->sessionCtx.ap.beacon = NULL;
9901 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009902#ifdef WLAN_FEATURE_P2P_DEBUG
9903 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
9904 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
9905 {
9906 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
9907 "GO got removed");
9908 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
9909 }
9910#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009911 }
9912 EXIT();
9913 return status;
9914}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009915
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309916#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9917static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
9918 struct net_device *dev)
9919{
9920 int ret;
9921
9922 vos_ssr_protect(__func__);
9923 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
9924 vos_ssr_unprotect(__func__);
9925
9926 return ret;
9927}
9928#else
9929static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
9930 struct net_device *dev)
9931{
9932 int ret;
9933
9934 vos_ssr_protect(__func__);
9935 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
9936 vos_ssr_unprotect(__func__);
9937
9938 return ret;
9939}
9940#endif
9941
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009942#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
9943
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309944static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309945 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009946 struct cfg80211_ap_settings *params)
9947{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309948 hdd_adapter_t *pAdapter;
9949 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309950 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009951
9952 ENTER();
9953
Girish Gowlib143d7a2015-02-18 19:39:55 +05309954 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009955 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05309957 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309958 return -ENODEV;
9959 }
9960
9961 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9962 if (NULL == pAdapter)
9963 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309965 "%s: HDD adapter is Null", __func__);
9966 return -ENODEV;
9967 }
9968
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309969 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9970 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
9971 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309972 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9973 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309975 "%s: HDD adapter magic is invalid", __func__);
9976 return -ENODEV;
9977 }
9978
9979 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309980 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309981 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309982 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309983 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309984 }
9985
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309986 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
9987 __func__, hdd_device_modetoString(pAdapter->device_mode),
9988 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309989
9990 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009991 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009992 )
9993 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309994 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009995
9996 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309997
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009998 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309999 {
10000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10001 FL("already beacon info added to session(%d)"),
10002 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010003 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010004 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010005
Girish Gowlib143d7a2015-02-18 19:39:55 +053010006#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10007 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10008 &new,
10009 &params->beacon);
10010#else
10011 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10012 &new,
10013 &params->beacon,
10014 params->dtim_period);
10015#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010016
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010017 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010018 {
10019 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010020 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010021 return -EINVAL;
10022 }
10023 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010024#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010025 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10026#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10027 params->channel, params->channel_type);
10028#else
10029 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10030#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010031#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010032 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010033 params->ssid_len, params->hidden_ssid,
10034 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010035 }
10036
10037 EXIT();
10038 return status;
10039}
10040
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010041static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10042 struct net_device *dev,
10043 struct cfg80211_ap_settings *params)
10044{
10045 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010046
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010047 vos_ssr_protect(__func__);
10048 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10049 vos_ssr_unprotect(__func__);
10050
10051 return ret;
10052}
10053
10054static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010055 struct net_device *dev,
10056 struct cfg80211_beacon_data *params)
10057{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010058 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010059 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010060 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010061
10062 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010063
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010064 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10065 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10066 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010067 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010068 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010069
10070 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10071 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010072 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010073 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010074 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010075 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010076
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010077 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010078 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010079 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010080 {
10081 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010082
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010083 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010084
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010085 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010086 {
10087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10088 FL("session(%d) beacon data points to NULL"),
10089 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010090 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010091 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010092
10093 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10094
10095 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010096 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010097 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010098 return -EINVAL;
10099 }
10100
10101 pAdapter->sessionCtx.ap.beacon = new;
10102
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010103 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10104 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010105 }
10106
10107 EXIT();
10108 return status;
10109}
10110
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010111static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10112 struct net_device *dev,
10113 struct cfg80211_beacon_data *params)
10114{
10115 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010116
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010117 vos_ssr_protect(__func__);
10118 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10119 vos_ssr_unprotect(__func__);
10120
10121 return ret;
10122}
10123
10124#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010125
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010126static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010127 struct net_device *dev,
10128 struct bss_parameters *params)
10129{
10130 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010131 hdd_context_t *pHddCtx;
10132 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010133
10134 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010135
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010136 if (NULL == pAdapter)
10137 {
10138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10139 "%s: HDD adapter is Null", __func__);
10140 return -ENODEV;
10141 }
10142 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010143 ret = wlan_hdd_validate_context(pHddCtx);
10144 if (0 != ret)
10145 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010146 return ret;
10147 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010148 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10149 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10150 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010151 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10152 __func__, hdd_device_modetoString(pAdapter->device_mode),
10153 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010154
10155 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010156 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010157 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 {
10159 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10160 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010161 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010162 {
10163 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010164 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010165 }
10166
10167 EXIT();
10168 return 0;
10169}
10170
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010171static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10172 struct net_device *dev,
10173 struct bss_parameters *params)
10174{
10175 int ret;
10176
10177 vos_ssr_protect(__func__);
10178 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10179 vos_ssr_unprotect(__func__);
10180
10181 return ret;
10182}
Kiet Lam10841362013-11-01 11:36:50 +053010183/* FUNCTION: wlan_hdd_change_country_code_cd
10184* to wait for contry code completion
10185*/
10186void* wlan_hdd_change_country_code_cb(void *pAdapter)
10187{
10188 hdd_adapter_t *call_back_pAdapter = pAdapter;
10189 complete(&call_back_pAdapter->change_country_code);
10190 return NULL;
10191}
10192
Jeff Johnson295189b2012-06-20 16:38:30 -070010193/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010194 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010195 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10196 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010197int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010198 struct net_device *ndev,
10199 enum nl80211_iftype type,
10200 u32 *flags,
10201 struct vif_params *params
10202 )
10203{
10204 struct wireless_dev *wdev;
10205 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010206 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010207 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010208 tCsrRoamProfile *pRoamProfile = NULL;
10209 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010210 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010211 eMib_dot11DesiredBssType connectedBssType;
10212 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010213 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010214
10215 ENTER();
10216
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010217 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010218 {
10219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10220 "%s: Adapter context is null", __func__);
10221 return VOS_STATUS_E_FAILURE;
10222 }
10223
10224 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10225 if (!pHddCtx)
10226 {
10227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10228 "%s: HDD context is null", __func__);
10229 return VOS_STATUS_E_FAILURE;
10230 }
10231
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010232 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10233 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10234 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010235 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010236 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010237 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010238 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010239 }
10240
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010241 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10242 __func__, hdd_device_modetoString(pAdapter->device_mode),
10243 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010244
Agarwal Ashish51325b52014-06-16 16:50:49 +053010245 if (vos_max_concurrent_connections_reached()) {
10246 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10247 return -EINVAL;
10248 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010249 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010250 wdev = ndev->ieee80211_ptr;
10251
10252#ifdef WLAN_BTAMP_FEATURE
10253 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10254 (NL80211_IFTYPE_ADHOC == type)||
10255 (NL80211_IFTYPE_AP == type)||
10256 (NL80211_IFTYPE_P2P_GO == type))
10257 {
10258 pHddCtx->isAmpAllowed = VOS_FALSE;
10259 // stop AMP traffic
10260 status = WLANBAP_StopAmp();
10261 if(VOS_STATUS_SUCCESS != status )
10262 {
10263 pHddCtx->isAmpAllowed = VOS_TRUE;
10264 hddLog(VOS_TRACE_LEVEL_FATAL,
10265 "%s: Failed to stop AMP", __func__);
10266 return -EINVAL;
10267 }
10268 }
10269#endif //WLAN_BTAMP_FEATURE
10270 /* Reset the current device mode bit mask*/
10271 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10272
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010273 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10274 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10275 (type == NL80211_IFTYPE_P2P_GO)))
10276 {
10277 /* Notify Mode change in case of concurrency.
10278 * Below function invokes TDLS teardown Functionality Since TDLS is
10279 * not Supported in case of concurrency i.e Once P2P session
10280 * is detected disable offchannel and teardown TDLS links
10281 */
10282 hddLog(LOG1,
10283 FL("Device mode = %d Interface type = %d"),
10284 pAdapter->device_mode, type);
10285 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10286 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010287
Jeff Johnson295189b2012-06-20 16:38:30 -070010288 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010289 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010290 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010291 )
10292 {
10293 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010294 if (!pWextState)
10295 {
10296 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10297 "%s: pWextState is null", __func__);
10298 return VOS_STATUS_E_FAILURE;
10299 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010300 pRoamProfile = &pWextState->roamProfile;
10301 LastBSSType = pRoamProfile->BSSType;
10302
10303 switch (type)
10304 {
10305 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010306 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010307 hddLog(VOS_TRACE_LEVEL_INFO,
10308 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10309 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010310#ifdef WLAN_FEATURE_11AC
10311 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10312 {
10313 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10314 }
10315#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010316 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010317 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010318 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010319 //Check for sub-string p2p to confirm its a p2p interface
10320 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010321 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010322#ifdef FEATURE_WLAN_TDLS
10323 mutex_lock(&pHddCtx->tdls_lock);
10324 wlan_hdd_tdls_exit(pAdapter, TRUE);
10325 mutex_unlock(&pHddCtx->tdls_lock);
10326#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010327 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10328 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10329 }
10330 else
10331 {
10332 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010333 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010334 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010335 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010336
Jeff Johnson295189b2012-06-20 16:38:30 -070010337 case NL80211_IFTYPE_ADHOC:
10338 hddLog(VOS_TRACE_LEVEL_INFO,
10339 "%s: setting interface Type to ADHOC", __func__);
10340 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10341 pRoamProfile->phyMode =
10342 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010343 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010344 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010345 hdd_set_ibss_ops( pAdapter );
10346 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010347
10348 status = hdd_sta_id_hash_attach(pAdapter);
10349 if (VOS_STATUS_SUCCESS != status) {
10350 hddLog(VOS_TRACE_LEVEL_ERROR,
10351 FL("Failed to initialize hash for IBSS"));
10352 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010353 break;
10354
10355 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010356 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010357 {
10358 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10359 "%s: setting interface Type to %s", __func__,
10360 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10361
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010362 //Cancel any remain on channel for GO mode
10363 if (NL80211_IFTYPE_P2P_GO == type)
10364 {
10365 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10366 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010367 if (NL80211_IFTYPE_AP == type)
10368 {
10369 /* As Loading WLAN Driver one interface being created for p2p device
10370 * address. This will take one HW STA and the max number of clients
10371 * that can connect to softAP will be reduced by one. so while changing
10372 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10373 * interface as it is not required in SoftAP mode.
10374 */
10375
10376 // Get P2P Adapter
10377 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10378
10379 if (pP2pAdapter)
10380 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010381 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010382 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010383 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10384 }
10385 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010386 //Disable IMPS & BMPS for SAP/GO
10387 if(VOS_STATUS_E_FAILURE ==
10388 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10389 {
10390 //Fail to Exit BMPS
10391 VOS_ASSERT(0);
10392 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010393
10394 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10395
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010396#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010397
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010398 /* A Mutex Lock is introduced while changing the mode to
10399 * protect the concurrent access for the Adapters by TDLS
10400 * module.
10401 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010402 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010403#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010404 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010405 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010406 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010407 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10408 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010409#ifdef FEATURE_WLAN_TDLS
10410 mutex_unlock(&pHddCtx->tdls_lock);
10411#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010412 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10413 (pConfig->apRandomBssidEnabled))
10414 {
10415 /* To meet Android requirements create a randomized
10416 MAC address of the form 02:1A:11:Fx:xx:xx */
10417 get_random_bytes(&ndev->dev_addr[3], 3);
10418 ndev->dev_addr[0] = 0x02;
10419 ndev->dev_addr[1] = 0x1A;
10420 ndev->dev_addr[2] = 0x11;
10421 ndev->dev_addr[3] |= 0xF0;
10422 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10423 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010424 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10425 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010426 }
10427
Jeff Johnson295189b2012-06-20 16:38:30 -070010428 hdd_set_ap_ops( pAdapter->dev );
10429
Kiet Lam10841362013-11-01 11:36:50 +053010430 /* This is for only SAP mode where users can
10431 * control country through ini.
10432 * P2P GO follows station country code
10433 * acquired during the STA scanning. */
10434 if((NL80211_IFTYPE_AP == type) &&
10435 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10436 {
10437 int status = 0;
10438 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10439 "%s: setting country code from INI ", __func__);
10440 init_completion(&pAdapter->change_country_code);
10441 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10442 (void *)(tSmeChangeCountryCallback)
10443 wlan_hdd_change_country_code_cb,
10444 pConfig->apCntryCode, pAdapter,
10445 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010446 eSIR_FALSE,
10447 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010448 if (eHAL_STATUS_SUCCESS == status)
10449 {
10450 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010451 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010452 &pAdapter->change_country_code,
10453 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010454 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010455 {
10456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010457 FL("SME Timed out while setting country code %ld"),
10458 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010459
10460 if (pHddCtx->isLogpInProgress)
10461 {
10462 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10463 "%s: LOGP in Progress. Ignore!!!", __func__);
10464 return -EAGAIN;
10465 }
Kiet Lam10841362013-11-01 11:36:50 +053010466 }
10467 }
10468 else
10469 {
10470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010471 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010472 return -EINVAL;
10473 }
10474 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010475 status = hdd_init_ap_mode(pAdapter);
10476 if(status != VOS_STATUS_SUCCESS)
10477 {
10478 hddLog(VOS_TRACE_LEVEL_FATAL,
10479 "%s: Error initializing the ap mode", __func__);
10480 return -EINVAL;
10481 }
10482 hdd_set_conparam(1);
10483
Nirav Shah7e3c8132015-06-22 23:51:42 +053010484 status = hdd_sta_id_hash_attach(pAdapter);
10485 if (VOS_STATUS_SUCCESS != status)
10486 {
10487 hddLog(VOS_TRACE_LEVEL_ERROR,
10488 FL("Failed to initialize hash for AP"));
10489 return -EINVAL;
10490 }
10491
Jeff Johnson295189b2012-06-20 16:38:30 -070010492 /*interface type changed update in wiphy structure*/
10493 if(wdev)
10494 {
10495 wdev->iftype = type;
10496 pHddCtx->change_iface = type;
10497 }
10498 else
10499 {
10500 hddLog(VOS_TRACE_LEVEL_ERROR,
10501 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10502 return -EINVAL;
10503 }
10504 goto done;
10505 }
10506
10507 default:
10508 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10509 __func__);
10510 return -EOPNOTSUPP;
10511 }
10512 }
10513 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010514 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010515 )
10516 {
10517 switch(type)
10518 {
10519 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010520 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010521 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010522
10523 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010524#ifdef FEATURE_WLAN_TDLS
10525
10526 /* A Mutex Lock is introduced while changing the mode to
10527 * protect the concurrent access for the Adapters by TDLS
10528 * module.
10529 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010530 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010531#endif
c_hpothu002231a2015-02-05 14:58:51 +053010532 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010533 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010534 //Check for sub-string p2p to confirm its a p2p interface
10535 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010536 {
10537 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10538 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10539 }
10540 else
10541 {
10542 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010543 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010544 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010545 hdd_set_conparam(0);
10546 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010547 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10548 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010549#ifdef FEATURE_WLAN_TDLS
10550 mutex_unlock(&pHddCtx->tdls_lock);
10551#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010552 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010553 if( VOS_STATUS_SUCCESS != status )
10554 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010555 /* In case of JB, for P2P-GO, only change interface will be called,
10556 * This is the right place to enable back bmps_imps()
10557 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010558 if (pHddCtx->hdd_wlan_suspended)
10559 {
10560 hdd_set_pwrparams(pHddCtx);
10561 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010562 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010563 goto done;
10564 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010565 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010566 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010567 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10568 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010569 goto done;
10570 default:
10571 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10572 __func__);
10573 return -EOPNOTSUPP;
10574
10575 }
10576
10577 }
10578 else
10579 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010580 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10581 __func__, hdd_device_modetoString(pAdapter->device_mode),
10582 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010583 return -EOPNOTSUPP;
10584 }
10585
10586
10587 if(pRoamProfile)
10588 {
10589 if ( LastBSSType != pRoamProfile->BSSType )
10590 {
10591 /*interface type changed update in wiphy structure*/
10592 wdev->iftype = type;
10593
10594 /*the BSS mode changed, We need to issue disconnect
10595 if connected or in IBSS disconnect state*/
10596 if ( hdd_connGetConnectedBssType(
10597 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10598 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10599 {
10600 /*need to issue a disconnect to CSR.*/
10601 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10602 if( eHAL_STATUS_SUCCESS ==
10603 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10604 pAdapter->sessionId,
10605 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10606 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010607 ret = wait_for_completion_interruptible_timeout(
10608 &pAdapter->disconnect_comp_var,
10609 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10610 if (ret <= 0)
10611 {
10612 hddLog(VOS_TRACE_LEVEL_ERROR,
10613 FL("wait on disconnect_comp_var failed %ld"), ret);
10614 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010615 }
10616 }
10617 }
10618 }
10619
10620done:
10621 /*set bitmask based on updated value*/
10622 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010623
10624 /* Only STA mode support TM now
10625 * all other mode, TM feature should be disabled */
10626 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10627 (~VOS_STA & pHddCtx->concurrency_mode) )
10628 {
10629 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10630 }
10631
Jeff Johnson295189b2012-06-20 16:38:30 -070010632#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010633 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010634 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010635 {
10636 //we are ok to do AMP
10637 pHddCtx->isAmpAllowed = VOS_TRUE;
10638 }
10639#endif //WLAN_BTAMP_FEATURE
10640 EXIT();
10641 return 0;
10642}
10643
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010644/*
10645 * FUNCTION: wlan_hdd_cfg80211_change_iface
10646 * wrapper function to protect the actual implementation from SSR.
10647 */
10648int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10649 struct net_device *ndev,
10650 enum nl80211_iftype type,
10651 u32 *flags,
10652 struct vif_params *params
10653 )
10654{
10655 int ret;
10656
10657 vos_ssr_protect(__func__);
10658 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10659 vos_ssr_unprotect(__func__);
10660
10661 return ret;
10662}
10663
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010664#ifdef FEATURE_WLAN_TDLS
10665static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010666 struct net_device *dev,
10667#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10668 const u8 *mac,
10669#else
10670 u8 *mac,
10671#endif
10672 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010673{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010674 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010675 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010676 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010677 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010678 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010679 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010680
10681 ENTER();
10682
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010683 if (!dev) {
10684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10685 return -EINVAL;
10686 }
10687
10688 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10689 if (!pAdapter) {
10690 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
10691 return -EINVAL;
10692 }
10693
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010694 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010695 {
10696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10697 "Invalid arguments");
10698 return -EINVAL;
10699 }
Hoonki Lee27511902013-03-14 18:19:06 -070010700
10701 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
10702 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
10703 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070010705 "%s: TDLS mode is disabled OR not enabled in FW."
10706 MAC_ADDRESS_STR " Request declined.",
10707 __func__, MAC_ADDR_ARRAY(mac));
10708 return -ENOTSUPP;
10709 }
10710
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010711 if (pHddCtx->isLogpInProgress)
10712 {
10713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10714 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053010715 wlan_hdd_tdls_set_link_status(pAdapter,
10716 mac,
10717 eTDLS_LINK_IDLE,
10718 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010719 return -EBUSY;
10720 }
10721
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010722 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053010723 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010724
10725 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010727 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
10728 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010729 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010730 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010731 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010732
10733 /* in add station, we accept existing valid staId if there is */
10734 if ((0 == update) &&
10735 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
10736 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010737 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010739 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010740 " link_status %d. staId %d. add station ignored.",
10741 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010742 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010743 return 0;
10744 }
10745 /* in change station, we accept only when staId is valid */
10746 if ((1 == update) &&
10747 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
10748 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
10749 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010750 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010752 "%s: " MAC_ADDRESS_STR
10753 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010754 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
10755 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
10756 mutex_unlock(&pHddCtx->tdls_lock);
10757 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010758 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010759 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010760
10761 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053010762 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010763 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10765 "%s: " MAC_ADDRESS_STR
10766 " TDLS setup is ongoing. Request declined.",
10767 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070010768 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010769 }
10770
10771 /* first to check if we reached to maximum supported TDLS peer.
10772 TODO: for now, return -EPERM looks working fine,
10773 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010774 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
10775 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010776 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010777 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10778 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010779 " TDLS Max peer already connected. Request declined."
10780 " Num of peers (%d), Max allowed (%d).",
10781 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
10782 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010783 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010784 }
10785 else
10786 {
10787 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010788 mutex_lock(&pHddCtx->tdls_lock);
10789 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010790 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010791 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010792 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10794 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
10795 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010796 return -EPERM;
10797 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010798 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010799 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010800 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053010801 wlan_hdd_tdls_set_link_status(pAdapter,
10802 mac,
10803 eTDLS_LINK_CONNECTING,
10804 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010805
Jeff Johnsond75fe012013-04-06 10:53:06 -070010806 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010807 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010808 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010810 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010811 if(StaParams->htcap_present)
10812 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010814 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010816 "ht_capa->extended_capabilities: %0x",
10817 StaParams->HTCap.extendedHtCapInfo);
10818 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010820 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010822 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010823 if(StaParams->vhtcap_present)
10824 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010826 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
10827 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
10828 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
10829 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010830 {
10831 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010833 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010834 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010835 "[%d]: %x ", i, StaParams->supported_rates[i]);
10836 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070010837 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010838 else if ((1 == update) && (NULL == StaParams))
10839 {
10840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10841 "%s : update is true, but staParams is NULL. Error!", __func__);
10842 return -EPERM;
10843 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010844
10845 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
10846
10847 if (!update)
10848 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010849 /*Before adding sta make sure that device exited from BMPS*/
10850 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
10851 {
10852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10853 "%s: Adding tdls peer sta. Disable BMPS", __func__);
10854 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10855 if (status != VOS_STATUS_SUCCESS) {
10856 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
10857 }
10858 }
10859
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010860 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010861 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010862 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010863 hddLog(VOS_TRACE_LEVEL_ERROR,
10864 FL("Failed to add TDLS peer STA. Enable Bmps"));
10865 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010866 return -EPERM;
10867 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010868 }
10869 else
10870 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010871 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010872 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010873 if (ret != eHAL_STATUS_SUCCESS) {
10874 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
10875 return -EPERM;
10876 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010877 }
10878
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010879 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010880 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
10881
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053010882 mutex_lock(&pHddCtx->tdls_lock);
10883 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
10884
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010885 if ((pTdlsPeer != NULL) &&
10886 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010887 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010888 hddLog(VOS_TRACE_LEVEL_ERROR,
10889 FL("peer link status %u"), pTdlsPeer->link_status);
10890 mutex_unlock(&pHddCtx->tdls_lock);
10891 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010892 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053010893 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010894
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010895 if (ret <= 0)
10896 {
10897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10898 "%s: timeout waiting for tdls add station indication %ld",
10899 __func__, ret);
10900 goto error;
10901 }
10902
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010903 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
10904 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010905 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010906 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010907 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010908 }
10909
10910 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070010911
10912error:
Atul Mittal115287b2014-07-08 13:26:33 +053010913 wlan_hdd_tdls_set_link_status(pAdapter,
10914 mac,
10915 eTDLS_LINK_IDLE,
10916 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010917 return -EPERM;
10918
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010919}
10920#endif
10921
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010922static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010923 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010924#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10925 const u8 *mac,
10926#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010927 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010928#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010929 struct station_parameters *params)
10930{
10931 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010932 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010933 hdd_context_t *pHddCtx;
10934 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010935 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010936 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010937#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010938 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010939 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010940 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053010941 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010942#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010943
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010944 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010945
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010946 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010947 if ((NULL == pAdapter))
10948 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010949 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010950 "invalid adapter ");
10951 return -EINVAL;
10952 }
10953
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010954 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10955 TRACE_CODE_HDD_CHANGE_STATION,
10956 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053010957 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010958
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010959 ret = wlan_hdd_validate_context(pHddCtx);
10960 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053010961 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010962 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010963 }
10964
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010965 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10966
10967 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010968 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010969 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10970 "invalid HDD station context");
10971 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010972 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010973 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
10974
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010975 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10976 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070010977 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010978 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070010979 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010980 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070010981 WLANTL_STA_AUTHENTICATED);
10982
Gopichand Nakkala29149562013-05-10 21:43:41 +053010983 if (status != VOS_STATUS_SUCCESS)
10984 {
10985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10986 "%s: Not able to change TL state to AUTHENTICATED", __func__);
10987 return -EINVAL;
10988 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010989 }
10990 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070010991 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
10992 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010993#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010994 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
10995 StaParams.capability = params->capability;
10996 StaParams.uapsd_queues = params->uapsd_queues;
10997 StaParams.max_sp = params->max_sp;
10998
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010999 /* Convert (first channel , number of channels) tuple to
11000 * the total list of channels. This goes with the assumption
11001 * that if the first channel is < 14, then the next channels
11002 * are an incremental of 1 else an incremental of 4 till the number
11003 * of channels.
11004 */
11005 if (0 != params->supported_channels_len) {
11006 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11007 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11008 {
11009 int wifi_chan_index;
11010 StaParams.supported_channels[j] = params->supported_channels[i];
11011 wifi_chan_index =
11012 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11013 no_of_channels = params->supported_channels[i+1];
11014 for(k=1; k <= no_of_channels; k++)
11015 {
11016 StaParams.supported_channels[j+1] =
11017 StaParams.supported_channels[j] + wifi_chan_index;
11018 j+=1;
11019 }
11020 }
11021 StaParams.supported_channels_len = j;
11022 }
11023 vos_mem_copy(StaParams.supported_oper_classes,
11024 params->supported_oper_classes,
11025 params->supported_oper_classes_len);
11026 StaParams.supported_oper_classes_len =
11027 params->supported_oper_classes_len;
11028
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011029 if (0 != params->ext_capab_len)
11030 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
11031 sizeof(StaParams.extn_capability));
11032
11033 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011034 {
11035 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011036 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011037 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011038
11039 StaParams.supported_rates_len = params->supported_rates_len;
11040
11041 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11042 * The supported_rates array , for all the structures propogating till Add Sta
11043 * to the firmware has to be modified , if the supplicant (ieee80211) is
11044 * modified to send more rates.
11045 */
11046
11047 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11048 */
11049 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11050 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11051
11052 if (0 != StaParams.supported_rates_len) {
11053 int i = 0;
11054 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11055 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011057 "Supported Rates with Length %d", StaParams.supported_rates_len);
11058 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011060 "[%d]: %0x", i, StaParams.supported_rates[i]);
11061 }
11062
11063 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011064 {
11065 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011066 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011067 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011068
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011069 if (0 != params->ext_capab_len ) {
11070 /*Define A Macro : TODO Sunil*/
11071 if ((1<<4) & StaParams.extn_capability[3]) {
11072 isBufSta = 1;
11073 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011074 /* TDLS Channel Switching Support */
11075 if ((1<<6) & StaParams.extn_capability[3]) {
11076 isOffChannelSupported = 1;
11077 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011078 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011079
11080 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
11081 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
11082
11083 /* TDLS Peer is WME/QoS capable */
11084 isQosWmmSta = TRUE;
11085 }
11086
11087 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11088 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11089 __func__, isQosWmmSta, StaParams.htcap_present);
11090
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011091 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11092 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011093 isOffChannelSupported,
11094 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011095
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011096 if (VOS_STATUS_SUCCESS != status) {
11097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11098 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11099 return -EINVAL;
11100 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011101 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11102
11103 if (VOS_STATUS_SUCCESS != status) {
11104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11105 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11106 return -EINVAL;
11107 }
11108 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011109#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011110 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011111 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011112 return status;
11113}
11114
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011115#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11116static int wlan_hdd_change_station(struct wiphy *wiphy,
11117 struct net_device *dev,
11118 const u8 *mac,
11119 struct station_parameters *params)
11120#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011121static int wlan_hdd_change_station(struct wiphy *wiphy,
11122 struct net_device *dev,
11123 u8 *mac,
11124 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011125#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011126{
11127 int ret;
11128
11129 vos_ssr_protect(__func__);
11130 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11131 vos_ssr_unprotect(__func__);
11132
11133 return ret;
11134}
11135
Jeff Johnson295189b2012-06-20 16:38:30 -070011136/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011137 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011138 * This function is used to initialize the key information
11139 */
11140#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011141static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011142 struct net_device *ndev,
11143 u8 key_index, bool pairwise,
11144 const u8 *mac_addr,
11145 struct key_params *params
11146 )
11147#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011148static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011149 struct net_device *ndev,
11150 u8 key_index, const u8 *mac_addr,
11151 struct key_params *params
11152 )
11153#endif
11154{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011155 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011156 tCsrRoamSetKey setKey;
11157 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011158 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011159 v_U32_t roamId= 0xFF;
11160 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011161 hdd_hostapd_state_t *pHostapdState;
11162 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011163 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011164 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011165
11166 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011167
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011168 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11169 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11170 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011171 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11172 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011173 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011174 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011175 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011176 }
11177
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011178 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11179 __func__, hdd_device_modetoString(pAdapter->device_mode),
11180 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011181
11182 if (CSR_MAX_NUM_KEY <= key_index)
11183 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011184 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011185 key_index);
11186
11187 return -EINVAL;
11188 }
11189
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011190 if (CSR_MAX_KEY_LEN < params->key_len)
11191 {
11192 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11193 params->key_len);
11194
11195 return -EINVAL;
11196 }
11197
11198 hddLog(VOS_TRACE_LEVEL_INFO,
11199 "%s: called with key index = %d & key length %d",
11200 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011201
11202 /*extract key idx, key len and key*/
11203 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11204 setKey.keyId = key_index;
11205 setKey.keyLength = params->key_len;
11206 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11207
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011208 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011209 {
11210 case WLAN_CIPHER_SUITE_WEP40:
11211 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11212 break;
11213
11214 case WLAN_CIPHER_SUITE_WEP104:
11215 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11216 break;
11217
11218 case WLAN_CIPHER_SUITE_TKIP:
11219 {
11220 u8 *pKey = &setKey.Key[0];
11221 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11222
11223 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11224
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011225 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011226
11227 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011228 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011229 |--------------|----------|----------|
11230 <---16bytes---><--8bytes--><--8bytes-->
11231
11232 */
11233 /*Sme expects the 32 bytes key to be in the below order
11234
11235 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011236 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011237 |--------------|----------|----------|
11238 <---16bytes---><--8bytes--><--8bytes-->
11239 */
11240 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011241 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011242
11243 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011244 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011245
11246 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011247 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011248
11249
11250 break;
11251 }
11252
11253 case WLAN_CIPHER_SUITE_CCMP:
11254 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11255 break;
11256
11257#ifdef FEATURE_WLAN_WAPI
11258 case WLAN_CIPHER_SUITE_SMS4:
11259 {
11260 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11261 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11262 params->key, params->key_len);
11263 return 0;
11264 }
11265#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011266
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011267#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011268 case WLAN_CIPHER_SUITE_KRK:
11269 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11270 break;
11271#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011272
11273#ifdef WLAN_FEATURE_11W
11274 case WLAN_CIPHER_SUITE_AES_CMAC:
11275 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011276 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011277#endif
11278
Jeff Johnson295189b2012-06-20 16:38:30 -070011279 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011280 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011281 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011282 status = -EOPNOTSUPP;
11283 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011284 }
11285
11286 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11287 __func__, setKey.encType);
11288
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011289 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011290#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11291 (!pairwise)
11292#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011293 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011294#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011295 )
11296 {
11297 /* set group key*/
11298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11299 "%s- %d: setting Broadcast key",
11300 __func__, __LINE__);
11301 setKey.keyDirection = eSIR_RX_ONLY;
11302 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11303 }
11304 else
11305 {
11306 /* set pairwise key*/
11307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11308 "%s- %d: setting pairwise key",
11309 __func__, __LINE__);
11310 setKey.keyDirection = eSIR_TX_RX;
11311 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11312 }
11313 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11314 {
11315 setKey.keyDirection = eSIR_TX_RX;
11316 /*Set the group key*/
11317 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11318 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011319
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011320 if ( 0 != status )
11321 {
11322 hddLog(VOS_TRACE_LEVEL_ERROR,
11323 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011324 status = -EINVAL;
11325 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011326 }
11327 /*Save the keys here and call sme_RoamSetKey for setting
11328 the PTK after peer joins the IBSS network*/
11329 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11330 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011331 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011332 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011333 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11334 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11335 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011336 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011337 if( pHostapdState->bssState == BSS_START )
11338 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011339 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11340 vos_status = wlan_hdd_check_ula_done(pAdapter);
11341
11342 if ( vos_status != VOS_STATUS_SUCCESS )
11343 {
11344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11345 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11346 __LINE__, vos_status );
11347
11348 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11349
11350 status = -EINVAL;
11351 goto end;
11352 }
11353
Jeff Johnson295189b2012-06-20 16:38:30 -070011354 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11355
11356 if ( status != eHAL_STATUS_SUCCESS )
11357 {
11358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11359 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11360 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011361 status = -EINVAL;
11362 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011363 }
11364 }
11365
11366 /* Saving WEP keys */
11367 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11368 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11369 {
11370 //Save the wep key in ap context. Issue setkey after the BSS is started.
11371 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11372 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11373 }
11374 else
11375 {
11376 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011377 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011378 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11379 }
11380 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011381 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11382 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011383 {
11384 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11385 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11386
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011387#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11388 if (!pairwise)
11389#else
11390 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11391#endif
11392 {
11393 /* set group key*/
11394 if (pHddStaCtx->roam_info.deferKeyComplete)
11395 {
11396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11397 "%s- %d: Perform Set key Complete",
11398 __func__, __LINE__);
11399 hdd_PerformRoamSetKeyComplete(pAdapter);
11400 }
11401 }
11402
Jeff Johnson295189b2012-06-20 16:38:30 -070011403 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11404
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011405 pWextState->roamProfile.Keys.defaultIndex = key_index;
11406
11407
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011408 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011409 params->key, params->key_len);
11410
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011411
Jeff Johnson295189b2012-06-20 16:38:30 -070011412 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11413
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011414 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011415 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011416 __func__, setKey.peerMac[0], setKey.peerMac[1],
11417 setKey.peerMac[2], setKey.peerMac[3],
11418 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011419 setKey.keyDirection);
11420
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011421 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011422
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011423 if ( vos_status != VOS_STATUS_SUCCESS )
11424 {
11425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011426 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11427 __LINE__, vos_status );
11428
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011429 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011430
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011431 status = -EINVAL;
11432 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011433
11434 }
11435
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011436#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011437 /* The supplicant may attempt to set the PTK once pre-authentication
11438 is done. Save the key in the UMAC and include it in the ADD BSS
11439 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011440 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011441 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011442 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011443 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11444 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011445 status = 0;
11446 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011447 }
11448 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11449 {
11450 hddLog(VOS_TRACE_LEVEL_ERROR,
11451 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011452 status = -EINVAL;
11453 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011454 }
11455#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011456
11457 /* issue set key request to SME*/
11458 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11459 pAdapter->sessionId, &setKey, &roamId );
11460
11461 if ( 0 != status )
11462 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011463 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011464 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11465 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011466 status = -EINVAL;
11467 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011468 }
11469
11470
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011471 /* in case of IBSS as there was no information available about WEP keys during
11472 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011473 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011474 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11475 !( ( IW_AUTH_KEY_MGMT_802_1X
11476 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011477 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11478 )
11479 &&
11480 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11481 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11482 )
11483 )
11484 {
11485 setKey.keyDirection = eSIR_RX_ONLY;
11486 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11487
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011488 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011489 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011490 __func__, setKey.peerMac[0], setKey.peerMac[1],
11491 setKey.peerMac[2], setKey.peerMac[3],
11492 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011493 setKey.keyDirection);
11494
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011495 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011496 pAdapter->sessionId, &setKey, &roamId );
11497
11498 if ( 0 != status )
11499 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011500 hddLog(VOS_TRACE_LEVEL_ERROR,
11501 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011502 __func__, status);
11503 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011504 status = -EINVAL;
11505 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011506 }
11507 }
11508 }
11509
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011510end:
11511 /* Need to clear any trace of key value in the memory.
11512 * Thus zero out the memory even though it is local
11513 * variable.
11514 */
11515 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011516 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011517 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011518}
11519
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011520#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11521static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11522 struct net_device *ndev,
11523 u8 key_index, bool pairwise,
11524 const u8 *mac_addr,
11525 struct key_params *params
11526 )
11527#else
11528static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11529 struct net_device *ndev,
11530 u8 key_index, const u8 *mac_addr,
11531 struct key_params *params
11532 )
11533#endif
11534{
11535 int ret;
11536 vos_ssr_protect(__func__);
11537#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11538 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11539 mac_addr, params);
11540#else
11541 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11542 params);
11543#endif
11544 vos_ssr_unprotect(__func__);
11545
11546 return ret;
11547}
11548
Jeff Johnson295189b2012-06-20 16:38:30 -070011549/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011550 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011551 * This function is used to get the key information
11552 */
11553#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011554static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011555 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011556 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011557 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011558 const u8 *mac_addr, void *cookie,
11559 void (*callback)(void *cookie, struct key_params*)
11560 )
11561#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011562static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011563 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011564 struct net_device *ndev,
11565 u8 key_index, const u8 *mac_addr, void *cookie,
11566 void (*callback)(void *cookie, struct key_params*)
11567 )
11568#endif
11569{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011570 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011571 hdd_wext_state_t *pWextState = NULL;
11572 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011573 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011574 hdd_context_t *pHddCtx;
11575 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011576
11577 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011578
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011579 if (NULL == pAdapter)
11580 {
11581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11582 "%s: HDD adapter is Null", __func__);
11583 return -ENODEV;
11584 }
11585
11586 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11587 ret = wlan_hdd_validate_context(pHddCtx);
11588 if (0 != ret)
11589 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011590 return ret;
11591 }
11592
11593 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11594 pRoamProfile = &(pWextState->roamProfile);
11595
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011596 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11597 __func__, hdd_device_modetoString(pAdapter->device_mode),
11598 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011599
Jeff Johnson295189b2012-06-20 16:38:30 -070011600 memset(&params, 0, sizeof(params));
11601
11602 if (CSR_MAX_NUM_KEY <= key_index)
11603 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011604 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011605 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011606 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011607
11608 switch(pRoamProfile->EncryptionType.encryptionType[0])
11609 {
11610 case eCSR_ENCRYPT_TYPE_NONE:
11611 params.cipher = IW_AUTH_CIPHER_NONE;
11612 break;
11613
11614 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11615 case eCSR_ENCRYPT_TYPE_WEP40:
11616 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11617 break;
11618
11619 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11620 case eCSR_ENCRYPT_TYPE_WEP104:
11621 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11622 break;
11623
11624 case eCSR_ENCRYPT_TYPE_TKIP:
11625 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11626 break;
11627
11628 case eCSR_ENCRYPT_TYPE_AES:
11629 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11630 break;
11631
11632 default:
11633 params.cipher = IW_AUTH_CIPHER_NONE;
11634 break;
11635 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011636
c_hpothuaaf19692014-05-17 17:01:48 +053011637 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11638 TRACE_CODE_HDD_CFG80211_GET_KEY,
11639 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011640
Jeff Johnson295189b2012-06-20 16:38:30 -070011641 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11642 params.seq_len = 0;
11643 params.seq = NULL;
11644 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11645 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011646 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011647 return 0;
11648}
11649
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011650#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11651static int wlan_hdd_cfg80211_get_key(
11652 struct wiphy *wiphy,
11653 struct net_device *ndev,
11654 u8 key_index, bool pairwise,
11655 const u8 *mac_addr, void *cookie,
11656 void (*callback)(void *cookie, struct key_params*)
11657 )
11658#else
11659static int wlan_hdd_cfg80211_get_key(
11660 struct wiphy *wiphy,
11661 struct net_device *ndev,
11662 u8 key_index, const u8 *mac_addr, void *cookie,
11663 void (*callback)(void *cookie, struct key_params*)
11664 )
11665#endif
11666{
11667 int ret;
11668
11669 vos_ssr_protect(__func__);
11670#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11671 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
11672 mac_addr, cookie, callback);
11673#else
11674 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
11675 callback);
11676#endif
11677 vos_ssr_unprotect(__func__);
11678
11679 return ret;
11680}
11681
Jeff Johnson295189b2012-06-20 16:38:30 -070011682/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011683 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011684 * This function is used to delete the key information
11685 */
11686#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011687static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011688 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011689 u8 key_index,
11690 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011691 const u8 *mac_addr
11692 )
11693#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011694static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011695 struct net_device *ndev,
11696 u8 key_index,
11697 const u8 *mac_addr
11698 )
11699#endif
11700{
11701 int status = 0;
11702
11703 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011704 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070011705 //it is observed that this is invalidating peer
11706 //key index whenever re-key is done. This is affecting data link.
11707 //It should be ok to ignore del_key.
11708#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011709 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
11710 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011711 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11712 tCsrRoamSetKey setKey;
11713 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011714
Jeff Johnson295189b2012-06-20 16:38:30 -070011715 ENTER();
11716
11717 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
11718 __func__,pAdapter->device_mode);
11719
11720 if (CSR_MAX_NUM_KEY <= key_index)
11721 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011722 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011723 key_index);
11724
11725 return -EINVAL;
11726 }
11727
11728 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11729 setKey.keyId = key_index;
11730
11731 if (mac_addr)
11732 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11733 else
11734 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
11735
11736 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
11737
11738 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011739 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011740 )
11741 {
11742
11743 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070011744 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11745 if( pHostapdState->bssState == BSS_START)
11746 {
11747 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011748
Jeff Johnson295189b2012-06-20 16:38:30 -070011749 if ( status != eHAL_STATUS_SUCCESS )
11750 {
11751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11752 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11753 __LINE__, status );
11754 }
11755 }
11756 }
11757 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011758 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070011759 )
11760 {
11761 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11762
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011763 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11764
11765 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011766 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011767 __func__, setKey.peerMac[0], setKey.peerMac[1],
11768 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070011769 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011770 if(pAdapter->sessionCtx.station.conn_info.connState ==
11771 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070011772 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011773 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011774 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011775
Jeff Johnson295189b2012-06-20 16:38:30 -070011776 if ( 0 != status )
11777 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011778 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011779 "%s: sme_RoamSetKey failure, returned %d",
11780 __func__, status);
11781 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11782 return -EINVAL;
11783 }
11784 }
11785 }
11786#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011787 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011788 return status;
11789}
11790
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011791#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11792static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11793 struct net_device *ndev,
11794 u8 key_index,
11795 bool pairwise,
11796 const u8 *mac_addr
11797 )
11798#else
11799static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11800 struct net_device *ndev,
11801 u8 key_index,
11802 const u8 *mac_addr
11803 )
11804#endif
11805{
11806 int ret;
11807
11808 vos_ssr_protect(__func__);
11809#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11810 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
11811 mac_addr);
11812#else
11813 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
11814#endif
11815 vos_ssr_unprotect(__func__);
11816
11817 return ret;
11818}
11819
Jeff Johnson295189b2012-06-20 16:38:30 -070011820/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011821 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011822 * This function is used to set the default tx key index
11823 */
11824#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011825static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011826 struct net_device *ndev,
11827 u8 key_index,
11828 bool unicast, bool multicast)
11829#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011830static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011831 struct net_device *ndev,
11832 u8 key_index)
11833#endif
11834{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011835 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011836 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011837 hdd_wext_state_t *pWextState;
11838 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011839 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011840
11841 ENTER();
11842
Gopichand Nakkala29149562013-05-10 21:43:41 +053011843 if ((NULL == pAdapter))
11844 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011845 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011846 "invalid adapter");
11847 return -EINVAL;
11848 }
11849
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011850 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11851 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
11852 pAdapter->sessionId, key_index));
11853
Gopichand Nakkala29149562013-05-10 21:43:41 +053011854 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11855 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11856
11857 if ((NULL == pWextState) || (NULL == pHddStaCtx))
11858 {
11859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11860 "invalid Wext state or HDD context");
11861 return -EINVAL;
11862 }
11863
Arif Hussain6d2a3322013-11-17 19:50:10 -080011864 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011865 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011866
Jeff Johnson295189b2012-06-20 16:38:30 -070011867 if (CSR_MAX_NUM_KEY <= key_index)
11868 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011869 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011870 key_index);
11871
11872 return -EINVAL;
11873 }
11874
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011875 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11876 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011877 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011878 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011879 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011880 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011881
Jeff Johnson295189b2012-06-20 16:38:30 -070011882 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011883 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011884 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011885 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011886 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080011887 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011888 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080011889 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070011890 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011891 {
11892 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070011893 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011894
Jeff Johnson295189b2012-06-20 16:38:30 -070011895 tCsrRoamSetKey setKey;
11896 v_U32_t roamId= 0xFF;
11897 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011898
11899 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011900 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011901
Jeff Johnson295189b2012-06-20 16:38:30 -070011902 Keys->defaultIndex = (u8)key_index;
11903 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11904 setKey.keyId = key_index;
11905 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011906
11907 vos_mem_copy(&setKey.Key[0],
11908 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011909 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011910
Gopichand Nakkala29149562013-05-10 21:43:41 +053011911 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011912
11913 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070011914 &pHddStaCtx->conn_info.bssId[0],
11915 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011916
Gopichand Nakkala29149562013-05-10 21:43:41 +053011917 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
11918 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
11919 eCSR_ENCRYPT_TYPE_WEP104)
11920 {
11921 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
11922 even though ap is configured for WEP-40 encryption. In this canse the key length
11923 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
11924 type(104) and switching encryption type to 40*/
11925 pWextState->roamProfile.EncryptionType.encryptionType[0] =
11926 eCSR_ENCRYPT_TYPE_WEP40;
11927 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
11928 eCSR_ENCRYPT_TYPE_WEP40;
11929 }
11930
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011931 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011932 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011933
Jeff Johnson295189b2012-06-20 16:38:30 -070011934 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011935 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011936 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011937
Jeff Johnson295189b2012-06-20 16:38:30 -070011938 if ( 0 != status )
11939 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011940 hddLog(VOS_TRACE_LEVEL_ERROR,
11941 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011942 status);
11943 return -EINVAL;
11944 }
11945 }
11946 }
11947
11948 /* In SoftAp mode setting key direction for default mode */
11949 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
11950 {
11951 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
11952 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
11953 (eCSR_ENCRYPT_TYPE_AES !=
11954 pWextState->roamProfile.EncryptionType.encryptionType[0])
11955 )
11956 {
11957 /* Saving key direction for default key index to TX default */
11958 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11959 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
11960 }
11961 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011962 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011963 return status;
11964}
11965
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011966#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11967static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11968 struct net_device *ndev,
11969 u8 key_index,
11970 bool unicast, bool multicast)
11971#else
11972static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11973 struct net_device *ndev,
11974 u8 key_index)
11975#endif
11976{
11977 int ret;
11978 vos_ssr_protect(__func__);
11979#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11980 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
11981 multicast);
11982#else
11983 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
11984#endif
11985 vos_ssr_unprotect(__func__);
11986
11987 return ret;
11988}
11989
Jeff Johnson295189b2012-06-20 16:38:30 -070011990/*
11991 * FUNCTION: wlan_hdd_cfg80211_inform_bss
11992 * This function is used to inform the BSS details to nl80211 interface.
11993 */
11994static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
11995 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
11996{
11997 struct net_device *dev = pAdapter->dev;
11998 struct wireless_dev *wdev = dev->ieee80211_ptr;
11999 struct wiphy *wiphy = wdev->wiphy;
12000 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12001 int chan_no;
12002 int ie_length;
12003 const char *ie;
12004 unsigned int freq;
12005 struct ieee80211_channel *chan;
12006 int rssi = 0;
12007 struct cfg80211_bss *bss = NULL;
12008
Jeff Johnson295189b2012-06-20 16:38:30 -070012009 if( NULL == pBssDesc )
12010 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012011 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012012 return bss;
12013 }
12014
12015 chan_no = pBssDesc->channelId;
12016 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12017 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12018
12019 if( NULL == ie )
12020 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012021 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012022 return bss;
12023 }
12024
12025#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12026 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12027 {
12028 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12029 }
12030 else
12031 {
12032 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12033 }
12034#else
12035 freq = ieee80211_channel_to_frequency(chan_no);
12036#endif
12037
12038 chan = __ieee80211_get_channel(wiphy, freq);
12039
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012040 if (!chan) {
12041 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12042 return NULL;
12043 }
12044
Abhishek Singhaee43942014-06-16 18:55:47 +053012045 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012046
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012047 return cfg80211_inform_bss(wiphy, chan,
12048#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12049 CFG80211_BSS_FTYPE_UNKNOWN,
12050#endif
12051 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012052 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012053 pBssDesc->capabilityInfo,
12054 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012055 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012056}
12057
12058
12059
12060/*
12061 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12062 * This function is used to inform the BSS details to nl80211 interface.
12063 */
12064struct cfg80211_bss*
12065wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12066 tSirBssDescription *bss_desc
12067 )
12068{
12069 /*
12070 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12071 already exists in bss data base of cfg80211 for that particular BSS ID.
12072 Using cfg80211_inform_bss_frame to update the bss entry instead of
12073 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12074 now there is no possibility to get the mgmt(probe response) frame from PE,
12075 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12076 cfg80211_inform_bss_frame.
12077 */
12078 struct net_device *dev = pAdapter->dev;
12079 struct wireless_dev *wdev = dev->ieee80211_ptr;
12080 struct wiphy *wiphy = wdev->wiphy;
12081 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012082#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12083 qcom_ie_age *qie_age = NULL;
12084 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12085#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012086 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012087#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012088 const char *ie =
12089 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12090 unsigned int freq;
12091 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012092 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012093 struct cfg80211_bss *bss_status = NULL;
12094 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12095 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012096 hdd_context_t *pHddCtx;
12097 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012098#ifdef WLAN_OPEN_SOURCE
12099 struct timespec ts;
12100#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012101
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012102
Wilson Yangf80a0542013-10-07 13:02:37 -070012103 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12104 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012105 if (0 != status)
12106 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012107 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012108 }
12109
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012110 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012111 if (!mgmt)
12112 {
12113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12114 "%s: memory allocation failed ", __func__);
12115 return NULL;
12116 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012117
Jeff Johnson295189b2012-06-20 16:38:30 -070012118 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012119
12120#ifdef WLAN_OPEN_SOURCE
12121 /* Android does not want the timestamp from the frame.
12122 Instead it wants a monotonic increasing value */
12123 get_monotonic_boottime(&ts);
12124 mgmt->u.probe_resp.timestamp =
12125 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12126#else
12127 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012128 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12129 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012130
12131#endif
12132
Jeff Johnson295189b2012-06-20 16:38:30 -070012133 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12134 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012135
12136#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12137 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12138 /* Assuming this is the last IE, copy at the end */
12139 ie_length -=sizeof(qcom_ie_age);
12140 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12141 qie_age->element_id = QCOM_VENDOR_IE_ID;
12142 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12143 qie_age->oui_1 = QCOM_OUI1;
12144 qie_age->oui_2 = QCOM_OUI2;
12145 qie_age->oui_3 = QCOM_OUI3;
12146 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
12147 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
12148#endif
12149
Jeff Johnson295189b2012-06-20 16:38:30 -070012150 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012151 if (bss_desc->fProbeRsp)
12152 {
12153 mgmt->frame_control |=
12154 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12155 }
12156 else
12157 {
12158 mgmt->frame_control |=
12159 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12160 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012161
12162#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012163 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012164 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12165 {
12166 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12167 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012168 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012169 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12170
12171 {
12172 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12173 }
12174 else
12175 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012176 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12177 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012178 kfree(mgmt);
12179 return NULL;
12180 }
12181#else
12182 freq = ieee80211_channel_to_frequency(chan_no);
12183#endif
12184 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012185 /*when the band is changed on the fly using the GUI, three things are done
12186 * 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)
12187 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12188 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12189 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12190 * and discards the channels correponding to previous band and calls back with zero bss results.
12191 * 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
12192 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12193 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12194 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12195 * So drop the bss and continue to next bss.
12196 */
12197 if(chan == NULL)
12198 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012199 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070012200 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012201 return NULL;
12202 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012203 /*To keep the rssi icon of the connected AP in the scan window
12204 *and the rssi icon of the wireless networks in sync
12205 * */
12206 if (( eConnectionState_Associated ==
12207 pAdapter->sessionCtx.station.conn_info.connState ) &&
12208 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12209 pAdapter->sessionCtx.station.conn_info.bssId,
12210 WNI_CFG_BSSID_LEN)) &&
12211 (pHddCtx->hdd_wlan_suspended == FALSE))
12212 {
12213 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12214 rssi = (pAdapter->rssi * 100);
12215 }
12216 else
12217 {
12218 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12219 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012220
Nirav Shah20ac06f2013-12-12 18:14:06 +053012221 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012222 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12223 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012224
Jeff Johnson295189b2012-06-20 16:38:30 -070012225 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12226 frame_len, rssi, GFP_KERNEL);
12227 kfree(mgmt);
12228 return bss_status;
12229}
12230
12231/*
12232 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12233 * This function is used to update the BSS data base of CFG8011
12234 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012235struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012236 tCsrRoamInfo *pRoamInfo
12237 )
12238{
12239 tCsrRoamConnectedProfile roamProfile;
12240 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12241 struct cfg80211_bss *bss = NULL;
12242
12243 ENTER();
12244
12245 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12246 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12247
12248 if (NULL != roamProfile.pBssDesc)
12249 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012250 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12251 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012252
12253 if (NULL == bss)
12254 {
12255 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12256 __func__);
12257 }
12258
12259 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12260 }
12261 else
12262 {
12263 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12264 __func__);
12265 }
12266 return bss;
12267}
12268
12269/*
12270 * FUNCTION: wlan_hdd_cfg80211_update_bss
12271 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012272static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12273 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012274 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012275{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012276 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012277 tCsrScanResultInfo *pScanResult;
12278 eHalStatus status = 0;
12279 tScanResultHandle pResult;
12280 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012281 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012282 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012283 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012284
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012285 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12286 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12287 NO_SESSION, pAdapter->sessionId));
12288
Wilson Yangf80a0542013-10-07 13:02:37 -070012289 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12290
12291 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070012292 {
Wilson Yangf80a0542013-10-07 13:02:37 -070012293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12294 "%s:LOGP in Progress. Ignore!!!",__func__);
12295 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070012296 }
12297
Wilson Yangf80a0542013-10-07 13:02:37 -070012298
12299 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053012300 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070012301 {
12302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12303 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
12304 return VOS_STATUS_E_PERM;
12305 }
12306
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012307 if (pAdapter->request != NULL)
12308 {
12309 if ((pAdapter->request->n_ssids == 1)
12310 && (pAdapter->request->ssids != NULL)
12311 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12312 is_p2p_scan = true;
12313 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012314 /*
12315 * start getting scan results and populate cgf80211 BSS database
12316 */
12317 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12318
12319 /* no scan results */
12320 if (NULL == pResult)
12321 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012322 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12323 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012324 wlan_hdd_get_frame_logs(pAdapter,
12325 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012326 return status;
12327 }
12328
12329 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12330
12331 while (pScanResult)
12332 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012333 /*
12334 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12335 * entry already exists in bss data base of cfg80211 for that
12336 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12337 * bss entry instead of cfg80211_inform_bss, But this call expects
12338 * mgmt packet as input. As of now there is no possibility to get
12339 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012340 * ieee80211_mgmt(probe response) and passing to c
12341 * fg80211_inform_bss_frame.
12342 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012343 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12344 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12345 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012346 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12347 continue; //Skip the non p2p bss entries
12348 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012349 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12350 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012351
Jeff Johnson295189b2012-06-20 16:38:30 -070012352
12353 if (NULL == bss_status)
12354 {
12355 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012356 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012357 }
12358 else
12359 {
Yue Maf49ba872013-08-19 12:04:25 -070012360 cfg80211_put_bss(
12361#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12362 wiphy,
12363#endif
12364 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012365 }
12366
12367 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12368 }
12369
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012370 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012371 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012372 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012373}
12374
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012375void
12376hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12377{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012378 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012379 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012380} /****** end hddPrintMacAddr() ******/
12381
12382void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012383hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012384{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012385 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012386 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012387 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12388 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12389 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012390} /****** end hddPrintPmkId() ******/
12391
12392//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12393//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12394
12395//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12396//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12397
12398#define dump_bssid(bssid) \
12399 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012400 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12401 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012402 }
12403
12404#define dump_pmkid(pMac, pmkid) \
12405 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012406 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12407 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012408 }
12409
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012410#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012411/*
12412 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12413 * This function is used to notify the supplicant of a new PMKSA candidate.
12414 */
12415int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012416 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012417 int index, bool preauth )
12418{
Jeff Johnsone7245742012-09-05 17:12:55 -070012419#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012420 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012421 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012422
12423 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012424 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012425
12426 if( NULL == pRoamInfo )
12427 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012428 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012429 return -EINVAL;
12430 }
12431
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012432 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12433 {
12434 dump_bssid(pRoamInfo->bssid);
12435 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012436 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012437 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012438#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012439 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012440}
12441#endif //FEATURE_WLAN_LFR
12442
Yue Maef608272013-04-08 23:09:17 -070012443#ifdef FEATURE_WLAN_LFR_METRICS
12444/*
12445 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12446 * 802.11r/LFR metrics reporting function to report preauth initiation
12447 *
12448 */
12449#define MAX_LFR_METRICS_EVENT_LENGTH 100
12450VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12451 tCsrRoamInfo *pRoamInfo)
12452{
12453 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12454 union iwreq_data wrqu;
12455
12456 ENTER();
12457
12458 if (NULL == pAdapter)
12459 {
12460 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12461 return VOS_STATUS_E_FAILURE;
12462 }
12463
12464 /* create the event */
12465 memset(&wrqu, 0, sizeof(wrqu));
12466 memset(metrics_notification, 0, sizeof(metrics_notification));
12467
12468 wrqu.data.pointer = metrics_notification;
12469 wrqu.data.length = scnprintf(metrics_notification,
12470 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12471 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12472
12473 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12474
12475 EXIT();
12476
12477 return VOS_STATUS_SUCCESS;
12478}
12479
12480/*
12481 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12482 * 802.11r/LFR metrics reporting function to report preauth completion
12483 * or failure
12484 */
12485VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12486 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12487{
12488 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12489 union iwreq_data wrqu;
12490
12491 ENTER();
12492
12493 if (NULL == pAdapter)
12494 {
12495 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12496 return VOS_STATUS_E_FAILURE;
12497 }
12498
12499 /* create the event */
12500 memset(&wrqu, 0, sizeof(wrqu));
12501 memset(metrics_notification, 0, sizeof(metrics_notification));
12502
12503 scnprintf(metrics_notification, sizeof(metrics_notification),
12504 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12505 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12506
12507 if (1 == preauth_status)
12508 strncat(metrics_notification, " TRUE", 5);
12509 else
12510 strncat(metrics_notification, " FALSE", 6);
12511
12512 wrqu.data.pointer = metrics_notification;
12513 wrqu.data.length = strlen(metrics_notification);
12514
12515 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12516
12517 EXIT();
12518
12519 return VOS_STATUS_SUCCESS;
12520}
12521
12522/*
12523 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12524 * 802.11r/LFR metrics reporting function to report handover initiation
12525 *
12526 */
12527VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12528 tCsrRoamInfo *pRoamInfo)
12529{
12530 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12531 union iwreq_data wrqu;
12532
12533 ENTER();
12534
12535 if (NULL == pAdapter)
12536 {
12537 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12538 return VOS_STATUS_E_FAILURE;
12539 }
12540
12541 /* create the event */
12542 memset(&wrqu, 0, sizeof(wrqu));
12543 memset(metrics_notification, 0, sizeof(metrics_notification));
12544
12545 wrqu.data.pointer = metrics_notification;
12546 wrqu.data.length = scnprintf(metrics_notification,
12547 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12548 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12549
12550 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12551
12552 EXIT();
12553
12554 return VOS_STATUS_SUCCESS;
12555}
12556#endif
12557
Jeff Johnson295189b2012-06-20 16:38:30 -070012558/*
12559 * FUNCTION: hdd_cfg80211_scan_done_callback
12560 * scanning callback function, called after finishing scan
12561 *
12562 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012563static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012564 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12565{
12566 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012567 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012568 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012569 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012570 struct cfg80211_scan_request *req = NULL;
12571 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012572 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012573 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012574 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012575 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012576
12577 ENTER();
12578
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012579 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012580 if (NULL == pHddCtx) {
12581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012582 goto allow_suspend;
12583 }
12584
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012585#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12586 if (!(pAdapter->dev->flags & IFF_UP))
12587 {
12588 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
12589 goto allow_suspend;
12590 }
12591#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012592 pScanInfo = &pHddCtx->scan_info;
12593
Jeff Johnson295189b2012-06-20 16:38:30 -070012594 hddLog(VOS_TRACE_LEVEL_INFO,
12595 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012596 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012597 __func__, halHandle, pContext, (int) scanId, (int) status);
12598
Kiet Lamac06e2c2013-10-23 16:25:07 +053012599 pScanInfo->mScanPendingCounter = 0;
12600
Jeff Johnson295189b2012-06-20 16:38:30 -070012601 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012602 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012603 &pScanInfo->scan_req_completion_event,
12604 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012605 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012606 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012607 hddLog(VOS_TRACE_LEVEL_ERROR,
12608 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012609 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012610 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012611 }
12612
Yue Maef608272013-04-08 23:09:17 -070012613 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012614 {
12615 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012616 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012617 }
12618
12619 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012620 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012621 {
12622 hddLog(VOS_TRACE_LEVEL_INFO,
12623 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012624 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012625 (int) scanId);
12626 }
12627
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012628 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012629 pAdapter);
12630
12631 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012632 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012633
12634
12635 /* If any client wait scan result through WEXT
12636 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012637 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012638 {
12639 /* The other scan request waiting for current scan finish
12640 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012641 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012642 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012643 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012644 }
12645 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012646 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012647 {
12648 struct net_device *dev = pAdapter->dev;
12649 union iwreq_data wrqu;
12650 int we_event;
12651 char *msg;
12652
12653 memset(&wrqu, '\0', sizeof(wrqu));
12654 we_event = SIOCGIWSCAN;
12655 msg = NULL;
12656 wireless_send_event(dev, we_event, &wrqu, msg);
12657 }
12658 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012659 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012660
12661 /* Get the Scan Req */
12662 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053012663 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012664
mukul sharmae7041822015-12-03 15:09:21 +053012665 if (!req || req->wiphy == NULL)
Jeff Johnson295189b2012-06-20 16:38:30 -070012666 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012667 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012668 pScanInfo->mScanPending = VOS_FALSE;
mukul sharmae7041822015-12-03 15:09:21 +053012669 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070012670 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012671 }
12672
Jeff Johnson295189b2012-06-20 16:38:30 -070012673 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070012674 /* Scan is no longer pending */
12675 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012676
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012677 /* last_scan_timestamp is used to decide if new scan
12678 * is needed or not on station interface. If last station
12679 * scan time and new station scan time is less then
12680 * last_scan_timestamp ; driver will return cached scan.
12681 */
12682 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12683 {
12684 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12685
12686 if ( req->n_channels )
12687 {
12688 for (i = 0; i < req->n_channels ; i++ )
12689 {
12690 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12691 }
12692 /* store no of channel scanned */
12693 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
12694 }
12695
12696 }
12697
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070012698 /*
12699 * cfg80211_scan_done informing NL80211 about completion
12700 * of scanning
12701 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012702 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
12703 {
12704 aborted = true;
12705 }
mukul sharmae7041822015-12-03 15:09:21 +053012706
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012707 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053012708
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012709 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070012710
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053012711 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
12712 ) && (pHddCtx->spoofMacAddr.isEnabled
12713 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053012714 /* Generate new random mac addr for next scan */
12715 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053012716
12717 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
12718 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053012719 }
12720
Jeff Johnsone7245742012-09-05 17:12:55 -070012721allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012722 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012723 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012724
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012725 /* Acquire wakelock to handle the case where APP's tries to suspend
12726 * immediatly after the driver gets connect request(i.e after scan)
12727 * from supplicant, this result in app's is suspending and not able
12728 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012729 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012730
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012731#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053012732 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012733#endif
12734
Jeff Johnson295189b2012-06-20 16:38:30 -070012735 EXIT();
12736 return 0;
12737}
12738
12739/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053012740 * FUNCTION: hdd_isConnectionInProgress
12741 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012742 *
12743 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012744v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012745{
12746 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12747 hdd_station_ctx_t *pHddStaCtx = NULL;
12748 hdd_adapter_t *pAdapter = NULL;
12749 VOS_STATUS status = 0;
12750 v_U8_t staId = 0;
12751 v_U8_t *staMac = NULL;
12752
c_hpothu9b781ba2013-12-30 20:57:45 +053012753 if (TRUE == pHddCtx->btCoexModeSet)
12754 {
12755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053012756 FL("BTCoex Mode operation in progress"));
12757 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053012758 }
12759
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012760 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12761
12762 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12763 {
12764 pAdapter = pAdapterNode->pAdapter;
12765
12766 if( pAdapter )
12767 {
12768 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012769 "%s: Adapter with device mode %s (%d) exists",
12770 __func__, hdd_device_modetoString(pAdapter->device_mode),
12771 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012772 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053012773 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12774 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
12775 (eConnectionState_Connecting ==
12776 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12777 {
12778 hddLog(VOS_TRACE_LEVEL_ERROR,
12779 "%s: %p(%d) Connection is in progress", __func__,
12780 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12781 return VOS_TRUE;
12782 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012783 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053012784 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012785 {
12786 hddLog(VOS_TRACE_LEVEL_ERROR,
12787 "%s: %p(%d) Reassociation is in progress", __func__,
12788 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12789 return VOS_TRUE;
12790 }
12791 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012792 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12793 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012794 {
12795 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12796 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012797 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012798 {
12799 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
12800 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012801 "%s: client " MAC_ADDRESS_STR
12802 " is in the middle of WPS/EAPOL exchange.", __func__,
12803 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012804 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012805 }
12806 }
12807 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
12808 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
12809 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012810 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12811 ptSapContext pSapCtx = NULL;
12812 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12813 if(pSapCtx == NULL){
12814 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12815 FL("psapCtx is NULL"));
12816 return VOS_FALSE;
12817 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012818 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
12819 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012820 if ((pSapCtx->aStaInfo[staId].isUsed) &&
12821 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012822 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012823 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012824
12825 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012826 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
12827 "middle of WPS/EAPOL exchange.", __func__,
12828 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012829 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012830 }
12831 }
12832 }
12833 }
12834 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12835 pAdapterNode = pNext;
12836 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053012837 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012838}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012839
12840/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012841 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070012842 * this scan respond to scan trigger and update cfg80211 scan database
12843 * later, scan dump command can be used to recieve scan results
12844 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012845int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080012846#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12847 struct net_device *dev,
12848#endif
12849 struct cfg80211_scan_request *request)
12850{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012851 hdd_adapter_t *pAdapter = NULL;
12852 hdd_context_t *pHddCtx = NULL;
12853 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012854 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012855 tCsrScanRequest scanRequest;
12856 tANI_U8 *channelList = NULL, i;
12857 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012858 int status;
12859 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012860 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012861 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053012862 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053012863 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012864 v_S7_t rssi=0;
12865 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012866
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012867#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
12868 struct net_device *dev = NULL;
12869 if (NULL == request)
12870 {
12871 hddLog(VOS_TRACE_LEVEL_ERROR,
12872 "%s: scan req param null", __func__);
12873 return -EINVAL;
12874 }
12875 dev = request->wdev->netdev;
12876#endif
12877
12878 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12879 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
12880 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12881
Jeff Johnson295189b2012-06-20 16:38:30 -070012882 ENTER();
12883
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012884 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12885 __func__, hdd_device_modetoString(pAdapter->device_mode),
12886 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012887
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012888 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012889 if (0 != status)
12890 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012891 return status;
12892 }
12893
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012894 if (NULL == pwextBuf)
12895 {
12896 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
12897 __func__);
12898 return -EIO;
12899 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012900 cfg_param = pHddCtx->cfg_ini;
12901 pScanInfo = &pHddCtx->scan_info;
12902
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012903 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12904 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
12905 {
12906 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
12907 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
12908 }
12909
Jeff Johnson295189b2012-06-20 16:38:30 -070012910#ifdef WLAN_BTAMP_FEATURE
12911 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012912 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070012913 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080012914 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012915 "%s: No scanning when AMP is on", __func__);
12916 return -EOPNOTSUPP;
12917 }
12918#endif
12919 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012920 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012921 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012922 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012923 "%s: Not scanning on device_mode = %s (%d)",
12924 __func__, hdd_device_modetoString(pAdapter->device_mode),
12925 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012926 return -EOPNOTSUPP;
12927 }
12928
12929 if (TRUE == pScanInfo->mScanPending)
12930 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012931 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
12932 {
12933 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
12934 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012935 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012936 }
12937
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053012938 // Don't allow scan if PNO scan is going on.
12939 if (pHddCtx->isPnoEnable)
12940 {
12941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12942 FL("pno scan in progress"));
12943 return -EBUSY;
12944 }
12945
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012946 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070012947 //Channel and action frame is pending
12948 //Otherwise Cancel Remain On Channel and allow Scan
12949 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012950 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070012951 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012952 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070012953 return -EBUSY;
12954 }
12955
Jeff Johnson295189b2012-06-20 16:38:30 -070012956 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
12957 {
12958 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080012959 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012960 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012961 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012962 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
12963 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012964 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012965 "%s: MAX TM Level Scan not allowed", __func__);
12966 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012967 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012968 }
12969 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
12970
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012971 /* Check if scan is allowed at this point of time.
12972 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012973 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012974 {
12975 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
12976 return -EBUSY;
12977 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012978
Jeff Johnson295189b2012-06-20 16:38:30 -070012979 vos_mem_zero( &scanRequest, sizeof(scanRequest));
12980
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012981 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
12982 * Becasue of this, driver is assuming that this is not wildcard scan and so
12983 * is not aging out the scan results.
12984 */
12985 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070012986 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012987 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012988 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012989
12990 if ((request->ssids) && (0 < request->n_ssids))
12991 {
12992 tCsrSSIDInfo *SsidInfo;
12993 int j;
12994 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
12995 /* Allocate num_ssid tCsrSSIDInfo structure */
12996 SsidInfo = scanRequest.SSIDs.SSIDList =
12997 ( tCsrSSIDInfo *)vos_mem_malloc(
12998 request->n_ssids*sizeof(tCsrSSIDInfo));
12999
13000 if(NULL == scanRequest.SSIDs.SSIDList)
13001 {
13002 hddLog(VOS_TRACE_LEVEL_ERROR,
13003 "%s: memory alloc failed SSIDInfo buffer", __func__);
13004 return -ENOMEM;
13005 }
13006
13007 /* copy all the ssid's and their length */
13008 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
13009 {
13010 /* get the ssid length */
13011 SsidInfo->SSID.length = request->ssids[j].ssid_len;
13012 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
13013 SsidInfo->SSID.length);
13014 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
13015 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
13016 j, SsidInfo->SSID.ssId);
13017 }
13018 /* set the scan type to active */
13019 scanRequest.scanType = eSIR_ACTIVE_SCAN;
13020 }
13021 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013022 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013023 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13024 TRACE_CODE_HDD_CFG80211_SCAN,
13025 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070013026 /* set the scan type to active */
13027 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070013028 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013029 else
13030 {
13031 /*Set the scan type to default type, in this case it is ACTIVE*/
13032 scanRequest.scanType = pScanInfo->scan_mode;
13033 }
13034 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
13035 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070013036
13037 /* set BSSType to default type */
13038 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
13039
13040 /*TODO: scan the requested channels only*/
13041
13042 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013043 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070013044 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013045 hddLog(VOS_TRACE_LEVEL_WARN,
13046 "No of Scan Channels exceeded limit: %d", request->n_channels);
13047 request->n_channels = MAX_CHANNEL;
13048 }
13049
13050 hddLog(VOS_TRACE_LEVEL_INFO,
13051 "No of Scan Channels: %d", request->n_channels);
13052
13053
13054 if( request->n_channels )
13055 {
13056 char chList [(request->n_channels*5)+1];
13057 int len;
13058 channelList = vos_mem_malloc( request->n_channels );
13059 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053013060 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013061 hddLog(VOS_TRACE_LEVEL_ERROR,
13062 "%s: memory alloc failed channelList", __func__);
13063 status = -ENOMEM;
13064 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053013065 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013066
13067 for( i = 0, len = 0; i < request->n_channels ; i++ )
13068 {
13069 channelList[i] = request->channels[i]->hw_value;
13070 len += snprintf(chList+len, 5, "%d ", channelList[i]);
13071 }
13072
Nirav Shah20ac06f2013-12-12 18:14:06 +053013073 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013074 "Channel-List: %s ", chList);
13075 }
c_hpothu53512302014-04-15 18:49:53 +053013076
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013077 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13078 scanRequest.ChannelInfo.ChannelList = channelList;
13079
13080 /* set requestType to full scan */
13081 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13082
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013083 /* if there is back to back scan happening in driver with in
13084 * nDeferScanTimeInterval interval driver should defer new scan request
13085 * and should provide last cached scan results instead of new channel list.
13086 * This rule is not applicable if scan is p2p scan.
13087 * This condition will work only in case when last request no of channels
13088 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013089 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013090 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013091 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013092
Sushant Kaushik86592172015-04-27 16:35:03 +053013093 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13094 /* if wps ie is NULL , then only defer scan */
13095 if ( pWpsIe == NULL &&
13096 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013097 {
13098 if ( pScanInfo->last_scan_timestamp !=0 &&
13099 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13100 {
13101 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13102 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13103 vos_mem_compare(pScanInfo->last_scan_channelList,
13104 channelList, pScanInfo->last_scan_numChannels))
13105 {
13106 hddLog(VOS_TRACE_LEVEL_WARN,
13107 " New and old station scan time differ is less then %u",
13108 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13109
13110 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013111 pAdapter);
13112
Agarwal Ashish57e84372014-12-05 18:26:53 +053013113 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013114 "Return old cached scan as all channels and no of channels are same");
13115
Agarwal Ashish57e84372014-12-05 18:26:53 +053013116 if (0 > ret)
13117 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013118
Agarwal Ashish57e84372014-12-05 18:26:53 +053013119 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013120
13121 status = eHAL_STATUS_SUCCESS;
13122 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013123 }
13124 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013125 }
13126
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013127 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13128 * search (Flush on both full scan and social scan but not on single
13129 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13130 */
13131
13132 /* Supplicant does single channel scan after 8-way handshake
13133 * and in that case driver shoudnt flush scan results. If
13134 * driver flushes the scan results here and unfortunately if
13135 * the AP doesnt respond to our probe req then association
13136 * fails which is not desired
13137 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013138 if ((request->n_ssids == 1)
13139 && (request->ssids != NULL)
13140 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13141 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013142
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013143 if( is_p2p_scan ||
13144 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013145 {
13146 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13147 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13148 pAdapter->sessionId );
13149 }
13150
13151 if( request->ie_len )
13152 {
13153 /* save this for future association (join requires this) */
13154 /*TODO: Array needs to be converted to dynamic allocation,
13155 * as multiple ie.s can be sent in cfg80211_scan_request structure
13156 * CR 597966
13157 */
13158 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13159 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13160 pScanInfo->scanAddIE.length = request->ie_len;
13161
13162 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13163 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13164 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013165 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013166 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013167 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013168 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13169 memcpy( pwextBuf->roamProfile.addIEScan,
13170 request->ie, request->ie_len);
13171 }
13172 else
13173 {
13174 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13175 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013176 }
13177
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013178 }
13179 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13180 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13181
13182 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13183 request->ie_len);
13184 if (pP2pIe != NULL)
13185 {
13186#ifdef WLAN_FEATURE_P2P_DEBUG
13187 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13188 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13189 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013190 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013191 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13192 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13193 "Go nego completed to Connection is started");
13194 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13195 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013196 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013197 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13198 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013199 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013200 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13201 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13202 "Disconnected state to Connection is started");
13203 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13204 "for 4way Handshake");
13205 }
13206#endif
13207
13208 /* no_cck will be set during p2p find to disable 11b rates */
13209 if(TRUE == request->no_cck)
13210 {
13211 hddLog(VOS_TRACE_LEVEL_INFO,
13212 "%s: This is a P2P Search", __func__);
13213 scanRequest.p2pSearch = 1;
13214
13215 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013216 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013217 /* set requestType to P2P Discovery */
13218 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13219 }
13220
13221 /*
13222 Skip Dfs Channel in case of P2P Search
13223 if it is set in ini file
13224 */
13225 if(cfg_param->skipDfsChnlInP2pSearch)
13226 {
13227 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013228 }
13229 else
13230 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013231 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013232 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013233
Agarwal Ashish4f616132013-12-30 23:32:50 +053013234 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013235 }
13236 }
13237
13238 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13239
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013240#ifdef FEATURE_WLAN_TDLS
13241 /* if tdls disagree scan right now, return immediately.
13242 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13243 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13244 */
13245 status = wlan_hdd_tdls_scan_callback (pAdapter,
13246 wiphy,
13247#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13248 dev,
13249#endif
13250 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013251 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013252 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053013253 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013254 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13255 "scan rejected %d", __func__, status);
13256 else
13257 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13258 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013259 hdd_wlan_block_scan_by_tdls();
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013260 return status;
13261 }
13262#endif
13263
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013264 /* acquire the wakelock to avoid the apps suspend during the scan. To
13265 * address the following issues.
13266 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13267 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13268 * for long time, this result in apps running at full power for long time.
13269 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13270 * be stuck in full power because of resume BMPS
13271 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013272 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013273
Nirav Shah20ac06f2013-12-12 18:14:06 +053013274 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13275 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013276 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13277 scanRequest.requestType, scanRequest.scanType,
13278 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013279 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13280
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013281 if (pHddCtx->spoofMacAddr.isEnabled &&
13282 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013283 {
13284 hddLog(VOS_TRACE_LEVEL_INFO,
13285 "%s: MAC Spoofing enabled for current scan", __func__);
13286 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13287 * to fill TxBds for probe request during current scan
13288 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013289 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013290 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013291
13292 if(status != VOS_STATUS_SUCCESS)
13293 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013294 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013295 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013296#ifdef FEATURE_WLAN_TDLS
13297 wlan_hdd_tdls_scan_done_callback(pAdapter);
13298#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013299 goto free_mem;
13300 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013301 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013302 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013303 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013304 pAdapter->sessionId, &scanRequest, &scanId,
13305 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013306
Jeff Johnson295189b2012-06-20 16:38:30 -070013307 if (eHAL_STATUS_SUCCESS != status)
13308 {
13309 hddLog(VOS_TRACE_LEVEL_ERROR,
13310 "%s: sme_ScanRequest returned error %d", __func__, status);
13311 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013312 if(eHAL_STATUS_RESOURCES == status)
13313 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013314 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13315 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013316 status = -EBUSY;
13317 } else {
13318 status = -EIO;
13319 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013320 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013321
13322#ifdef FEATURE_WLAN_TDLS
13323 wlan_hdd_tdls_scan_done_callback(pAdapter);
13324#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013325 goto free_mem;
13326 }
13327
13328 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013329 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013330 pAdapter->request = request;
13331 pScanInfo->scanId = scanId;
13332
13333 complete(&pScanInfo->scan_req_completion_event);
13334
13335free_mem:
13336 if( scanRequest.SSIDs.SSIDList )
13337 {
13338 vos_mem_free(scanRequest.SSIDs.SSIDList);
13339 }
13340
13341 if( channelList )
13342 vos_mem_free( channelList );
13343
13344 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013345 return status;
13346}
13347
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013348int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13349#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13350 struct net_device *dev,
13351#endif
13352 struct cfg80211_scan_request *request)
13353{
13354 int ret;
13355
13356 vos_ssr_protect(__func__);
13357 ret = __wlan_hdd_cfg80211_scan(wiphy,
13358#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13359 dev,
13360#endif
13361 request);
13362 vos_ssr_unprotect(__func__);
13363
13364 return ret;
13365}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013366
13367void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13368{
13369 v_U8_t iniDot11Mode =
13370 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13371 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13372
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013373 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13374 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013375 switch ( iniDot11Mode )
13376 {
13377 case eHDD_DOT11_MODE_AUTO:
13378 case eHDD_DOT11_MODE_11ac:
13379 case eHDD_DOT11_MODE_11ac_ONLY:
13380#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013381 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13382 sme_IsFeatureSupportedByFW(DOT11AC) )
13383 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13384 else
13385 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013386#else
13387 hddDot11Mode = eHDD_DOT11_MODE_11n;
13388#endif
13389 break;
13390 case eHDD_DOT11_MODE_11n:
13391 case eHDD_DOT11_MODE_11n_ONLY:
13392 hddDot11Mode = eHDD_DOT11_MODE_11n;
13393 break;
13394 default:
13395 hddDot11Mode = iniDot11Mode;
13396 break;
13397 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013398#ifdef WLAN_FEATURE_AP_HT40_24G
13399 if (operationChannel > SIR_11B_CHANNEL_END)
13400#endif
13401 {
13402 /* This call decides required channel bonding mode */
13403 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013404 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13405 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013406 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013407}
13408
Jeff Johnson295189b2012-06-20 16:38:30 -070013409/*
13410 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013411 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013412 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013413int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013414 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13415 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013416{
13417 int status = 0;
13418 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013419 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013420 v_U32_t roamId;
13421 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013422 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013423 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013424
13425 ENTER();
13426
13427 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013428 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13429
13430 status = wlan_hdd_validate_context(pHddCtx);
13431 if (status)
13432 {
Yue Mae36e3552014-03-05 17:06:20 -080013433 return status;
13434 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013435
Jeff Johnson295189b2012-06-20 16:38:30 -070013436 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13437 {
13438 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13439 return -EINVAL;
13440 }
13441
13442 pRoamProfile = &pWextState->roamProfile;
13443
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013444 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013445 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013446 hdd_station_ctx_t *pHddStaCtx;
13447 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013448
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013449 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13450
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013451 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013452 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13453 {
13454 /*QoS not enabled in cfg file*/
13455 pRoamProfile->uapsd_mask = 0;
13456 }
13457 else
13458 {
13459 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013460 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013461 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13462 }
13463
13464 pRoamProfile->SSIDs.numOfSSIDs = 1;
13465 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13466 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013467 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013468 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13469 ssid, ssid_len);
13470
13471 if (bssid)
13472 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013473 pValidBssid = bssid;
13474 }
13475 else if (bssid_hint)
13476 {
13477 pValidBssid = bssid_hint;
13478 }
13479 if (pValidBssid)
13480 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013481 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013482 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013483 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013484 /* Save BSSID in seperate variable as well, as RoamProfile
13485 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013486 case of join failure we should send valid BSSID to supplicant
13487 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013488 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013489 WNI_CFG_BSSID_LEN);
13490 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013491 else
13492 {
13493 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13494 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013495
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013496 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13497 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013498 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13499 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013500 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013501 /*set gen ie*/
13502 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13503 /*set auth*/
13504 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13505 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013506#ifdef FEATURE_WLAN_WAPI
13507 if (pAdapter->wapi_info.nWapiMode)
13508 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013509 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013510 switch (pAdapter->wapi_info.wapiAuthMode)
13511 {
13512 case WAPI_AUTH_MODE_PSK:
13513 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013514 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013515 pAdapter->wapi_info.wapiAuthMode);
13516 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13517 break;
13518 }
13519 case WAPI_AUTH_MODE_CERT:
13520 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013521 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013522 pAdapter->wapi_info.wapiAuthMode);
13523 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13524 break;
13525 }
13526 } // End of switch
13527 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13528 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13529 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013530 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013531 pRoamProfile->AuthType.numEntries = 1;
13532 pRoamProfile->EncryptionType.numEntries = 1;
13533 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13534 pRoamProfile->mcEncryptionType.numEntries = 1;
13535 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13536 }
13537 }
13538#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013539#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013540 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013541 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13542 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13543 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013544 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13545 sizeof (tSirGtkOffloadParams));
13546 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013547 }
13548#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013549 pRoamProfile->csrPersona = pAdapter->device_mode;
13550
Jeff Johnson32d95a32012-09-10 13:15:23 -070013551 if( operatingChannel )
13552 {
13553 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13554 pRoamProfile->ChannelInfo.numOfChannels = 1;
13555 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013556 else
13557 {
13558 pRoamProfile->ChannelInfo.ChannelList = NULL;
13559 pRoamProfile->ChannelInfo.numOfChannels = 0;
13560 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013561 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13562 {
13563 hdd_select_cbmode(pAdapter,operatingChannel);
13564 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013565
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013566 /*
13567 * Change conn_state to connecting before sme_RoamConnect(),
13568 * because sme_RoamConnect() has a direct path to call
13569 * hdd_smeRoamCallback(), which will change the conn_state
13570 * If direct path, conn_state will be accordingly changed
13571 * to NotConnected or Associated by either
13572 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13573 * in sme_RoamCallback()
13574 * if sme_RomConnect is to be queued,
13575 * Connecting state will remain until it is completed.
13576 * If connection state is not changed,
13577 * connection state will remain in eConnectionState_NotConnected state.
13578 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13579 * if conn state is eConnectionState_NotConnected.
13580 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13581 * informed of connect result indication which is an issue.
13582 */
13583
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013584 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13585 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013586 {
13587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013588 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013589 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13590 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013591 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013592 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013593 pAdapter->sessionId, pRoamProfile, &roamId);
13594
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013595 if ((eHAL_STATUS_SUCCESS != status) &&
13596 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13597 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013598
13599 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013600 hddLog(VOS_TRACE_LEVEL_ERROR,
13601 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13602 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013603 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013604 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013605 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013606 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013607
13608 pRoamProfile->ChannelInfo.ChannelList = NULL;
13609 pRoamProfile->ChannelInfo.numOfChannels = 0;
13610
Jeff Johnson295189b2012-06-20 16:38:30 -070013611 }
13612 else
13613 {
13614 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13615 return -EINVAL;
13616 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013617 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013618 return status;
13619}
13620
13621/*
13622 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
13623 * This function is used to set the authentication type (OPEN/SHARED).
13624 *
13625 */
13626static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
13627 enum nl80211_auth_type auth_type)
13628{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013629 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013630 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13631
13632 ENTER();
13633
13634 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013635 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070013636 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013637 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013638 hddLog(VOS_TRACE_LEVEL_INFO,
13639 "%s: set authentication type to AUTOSWITCH", __func__);
13640 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
13641 break;
13642
13643 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013644#ifdef WLAN_FEATURE_VOWIFI_11R
13645 case NL80211_AUTHTYPE_FT:
13646#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013647 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013648 "%s: set authentication type to OPEN", __func__);
13649 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
13650 break;
13651
13652 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013653 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013654 "%s: set authentication type to SHARED", __func__);
13655 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
13656 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013657#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013658 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013659 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013660 "%s: set authentication type to CCKM WPA", __func__);
13661 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
13662 break;
13663#endif
13664
13665
13666 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013667 hddLog(VOS_TRACE_LEVEL_ERROR,
13668 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013669 auth_type);
13670 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
13671 return -EINVAL;
13672 }
13673
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013674 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013675 pHddStaCtx->conn_info.authType;
13676 return 0;
13677}
13678
13679/*
13680 * FUNCTION: wlan_hdd_set_akm_suite
13681 * This function is used to set the key mgmt type(PSK/8021x).
13682 *
13683 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013684static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013685 u32 key_mgmt
13686 )
13687{
13688 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13689 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053013690 /* Should be in ieee802_11_defs.h */
13691#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
13692#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070013693 /*set key mgmt type*/
13694 switch(key_mgmt)
13695 {
13696 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053013697 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013698#ifdef WLAN_FEATURE_VOWIFI_11R
13699 case WLAN_AKM_SUITE_FT_PSK:
13700#endif
13701 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070013702 __func__);
13703 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
13704 break;
13705
13706 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053013707 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013708#ifdef WLAN_FEATURE_VOWIFI_11R
13709 case WLAN_AKM_SUITE_FT_8021X:
13710#endif
13711 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070013712 __func__);
13713 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13714 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013715#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013716#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
13717#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
13718 case WLAN_AKM_SUITE_CCKM:
13719 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
13720 __func__);
13721 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
13722 break;
13723#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070013724#ifndef WLAN_AKM_SUITE_OSEN
13725#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
13726 case WLAN_AKM_SUITE_OSEN:
13727 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
13728 __func__);
13729 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13730 break;
13731#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013732
13733 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013734 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013735 __func__, key_mgmt);
13736 return -EINVAL;
13737
13738 }
13739 return 0;
13740}
13741
13742/*
13743 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013744 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070013745 * (NONE/WEP40/WEP104/TKIP/CCMP).
13746 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013747static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
13748 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070013749 bool ucast
13750 )
13751{
13752 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013753 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013754 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13755
13756 ENTER();
13757
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013758 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013759 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013760 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070013761 __func__, cipher);
13762 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13763 }
13764 else
13765 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013766
Jeff Johnson295189b2012-06-20 16:38:30 -070013767 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013768 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013769 {
13770 case IW_AUTH_CIPHER_NONE:
13771 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13772 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013773
Jeff Johnson295189b2012-06-20 16:38:30 -070013774 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013775 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070013776 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013777
Jeff Johnson295189b2012-06-20 16:38:30 -070013778 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013779 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070013780 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013781
Jeff Johnson295189b2012-06-20 16:38:30 -070013782 case WLAN_CIPHER_SUITE_TKIP:
13783 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
13784 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013785
Jeff Johnson295189b2012-06-20 16:38:30 -070013786 case WLAN_CIPHER_SUITE_CCMP:
13787 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13788 break;
13789#ifdef FEATURE_WLAN_WAPI
13790 case WLAN_CIPHER_SUITE_SMS4:
13791 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
13792 break;
13793#endif
13794
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013795#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013796 case WLAN_CIPHER_SUITE_KRK:
13797 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
13798 break;
13799#endif
13800 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013801 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013802 __func__, cipher);
13803 return -EOPNOTSUPP;
13804 }
13805 }
13806
13807 if (ucast)
13808 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013809 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013810 __func__, encryptionType);
13811 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13812 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013813 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013814 encryptionType;
13815 }
13816 else
13817 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013818 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013819 __func__, encryptionType);
13820 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
13821 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
13822 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
13823 }
13824
13825 return 0;
13826}
13827
13828
13829/*
13830 * FUNCTION: wlan_hdd_cfg80211_set_ie
13831 * This function is used to parse WPA/RSN IE's.
13832 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013833int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013834#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13835 const u8 *ie,
13836#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013837 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013838#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013839 size_t ie_len
13840 )
13841{
13842 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013843#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13844 const u8 *genie = ie;
13845#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013846 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013847#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013848 v_U16_t remLen = ie_len;
13849#ifdef FEATURE_WLAN_WAPI
13850 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
13851 u16 *tmp;
13852 v_U16_t akmsuiteCount;
13853 int *akmlist;
13854#endif
13855 ENTER();
13856
13857 /* clear previous assocAddIE */
13858 pWextState->assocAddIE.length = 0;
13859 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013860 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013861
13862 while (remLen >= 2)
13863 {
13864 v_U16_t eLen = 0;
13865 v_U8_t elementId;
13866 elementId = *genie++;
13867 eLen = *genie++;
13868 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013869
Arif Hussain6d2a3322013-11-17 19:50:10 -080013870 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070013871 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013872
13873 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070013874 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013875 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013876 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 -070013877 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013878 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013879 "%s: Invalid WPA IE", __func__);
13880 return -EINVAL;
13881 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013882 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070013883 {
13884 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013885 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013886 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013887
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013888 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013889 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013890 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
13891 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013892 VOS_ASSERT(0);
13893 return -ENOMEM;
13894 }
13895 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13896 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13897 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013898
Jeff Johnson295189b2012-06-20 16:38:30 -070013899 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
13900 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13901 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13902 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013903 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
13904 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013905 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
13906 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
13907 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
13908 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
13909 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
13910 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013911 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053013912 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013913 {
13914 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013915 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013916 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013917
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013918 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013919 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013920 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13921 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013922 VOS_ASSERT(0);
13923 return -ENOMEM;
13924 }
13925 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13926 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13927 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013928
Jeff Johnson295189b2012-06-20 16:38:30 -070013929 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13930 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13931 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013932#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013933 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
13934 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013935 /*Consider WFD IE, only for P2P Client */
13936 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
13937 {
13938 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013939 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013940 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013941
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013942 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013943 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013944 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13945 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013946 VOS_ASSERT(0);
13947 return -ENOMEM;
13948 }
13949 // WFD IE is saved to Additional IE ; it should be accumulated to handle
13950 // WPS IE + P2P IE + WFD IE
13951 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13952 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013953
Jeff Johnson295189b2012-06-20 16:38:30 -070013954 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13955 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13956 }
13957#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013958 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013959 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013960 HS20_OUI_TYPE_SIZE)) )
13961 {
13962 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013963 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013964 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013965
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013966 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013967 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013968 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13969 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013970 VOS_ASSERT(0);
13971 return -ENOMEM;
13972 }
13973 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13974 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013975
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013976 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13977 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13978 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013979 /* Appending OSEN Information Element in Assiciation Request */
13980 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
13981 OSEN_OUI_TYPE_SIZE)) )
13982 {
13983 v_U16_t curAddIELen = pWextState->assocAddIE.length;
13984 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
13985 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013986
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013987 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013988 {
13989 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13990 "Need bigger buffer space");
13991 VOS_ASSERT(0);
13992 return -ENOMEM;
13993 }
13994 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13995 pWextState->assocAddIE.length += eLen + 2;
13996
13997 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
13998 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13999 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14000 }
14001
Abhishek Singh4322e622015-06-10 15:42:54 +053014002 /* Update only for WPA IE */
14003 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
14004 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014005
14006 /* populating as ADDIE in beacon frames */
14007 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014008 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014009 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
14010 {
14011 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14012 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
14013 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14014 {
14015 hddLog(LOGE,
14016 "Coldn't pass "
14017 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
14018 }
14019 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
14020 else
14021 hddLog(LOGE,
14022 "Could not pass on "
14023 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
14024
14025 /* IBSS mode doesn't contain params->proberesp_ies still
14026 beaconIE's need to be populated in probe response frames */
14027 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
14028 {
14029 u16 rem_probe_resp_ie_len = eLen + 2;
14030 u8 probe_rsp_ie_len[3] = {0};
14031 u8 counter = 0;
14032
14033 /* Check Probe Resp Length if it is greater then 255 then
14034 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
14035 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
14036 not able Store More then 255 bytes into One Variable */
14037
14038 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
14039 {
14040 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
14041 {
14042 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
14043 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
14044 }
14045 else
14046 {
14047 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
14048 rem_probe_resp_ie_len = 0;
14049 }
14050 }
14051
14052 rem_probe_resp_ie_len = 0;
14053
14054 if (probe_rsp_ie_len[0] > 0)
14055 {
14056 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14057 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
14058 (tANI_U8*)(genie - 2),
14059 probe_rsp_ie_len[0], NULL,
14060 eANI_BOOLEAN_FALSE)
14061 == eHAL_STATUS_FAILURE)
14062 {
14063 hddLog(LOGE,
14064 "Could not pass"
14065 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
14066 }
14067 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
14068 }
14069
14070 if (probe_rsp_ie_len[1] > 0)
14071 {
14072 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14073 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
14074 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14075 probe_rsp_ie_len[1], NULL,
14076 eANI_BOOLEAN_FALSE)
14077 == eHAL_STATUS_FAILURE)
14078 {
14079 hddLog(LOGE,
14080 "Could not pass"
14081 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14082 }
14083 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14084 }
14085
14086 if (probe_rsp_ie_len[2] > 0)
14087 {
14088 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14089 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14090 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14091 probe_rsp_ie_len[2], NULL,
14092 eANI_BOOLEAN_FALSE)
14093 == eHAL_STATUS_FAILURE)
14094 {
14095 hddLog(LOGE,
14096 "Could not pass"
14097 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14098 }
14099 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14100 }
14101
14102 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14103 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14104 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14105 {
14106 hddLog(LOGE,
14107 "Could not pass"
14108 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14109 }
14110 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014111 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014112 break;
14113 case DOT11F_EID_RSN:
14114 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14115 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14116 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14117 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14118 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14119 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014120
Abhishek Singhb16f3562016-01-20 11:08:32 +053014121 /* Appending extended capabilities with Interworking or
14122 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053014123 *
14124 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053014125 * interworkingService or bsstransition bit is set to 1.
14126 * Driver is only interested in interworkingService and
14127 * bsstransition capability from supplicant.
14128 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053014129 * required from supplicat, it needs to be handled while
14130 * sending Assoc Req in LIM.
14131 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014132 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014133 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014134 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014135 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014136 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014137
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014138 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014139 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014140 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14141 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014142 VOS_ASSERT(0);
14143 return -ENOMEM;
14144 }
14145 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14146 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014147
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014148 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14149 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14150 break;
14151 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014152#ifdef FEATURE_WLAN_WAPI
14153 case WLAN_EID_WAPI:
14154 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014155 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014156 pAdapter->wapi_info.nWapiMode);
14157 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014158 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014159 akmsuiteCount = WPA_GET_LE16(tmp);
14160 tmp = tmp + 1;
14161 akmlist = (int *)(tmp);
14162 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14163 {
14164 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14165 }
14166 else
14167 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014168 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014169 VOS_ASSERT(0);
14170 return -EINVAL;
14171 }
14172
14173 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14174 {
14175 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014176 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014177 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014178 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014179 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014180 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014181 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014182 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014183 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14184 }
14185 break;
14186#endif
14187 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014188 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014189 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014190 /* when Unknown IE is received we should break and continue
14191 * to the next IE in the buffer instead we were returning
14192 * so changing this to break */
14193 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014194 }
14195 genie += eLen;
14196 remLen -= eLen;
14197 }
14198 EXIT();
14199 return 0;
14200}
14201
14202/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014203 * FUNCTION: hdd_isWPAIEPresent
14204 * Parse the received IE to find the WPA IE
14205 *
14206 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014207static bool hdd_isWPAIEPresent(
14208#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14209 const u8 *ie,
14210#else
14211 u8 *ie,
14212#endif
14213 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014214{
14215 v_U8_t eLen = 0;
14216 v_U16_t remLen = ie_len;
14217 v_U8_t elementId = 0;
14218
14219 while (remLen >= 2)
14220 {
14221 elementId = *ie++;
14222 eLen = *ie++;
14223 remLen -= 2;
14224 if (eLen > remLen)
14225 {
14226 hddLog(VOS_TRACE_LEVEL_ERROR,
14227 "%s: IE length is wrong %d", __func__, eLen);
14228 return FALSE;
14229 }
14230 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14231 {
14232 /* OUI - 0x00 0X50 0XF2
14233 WPA Information Element - 0x01
14234 WPA version - 0x01*/
14235 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14236 return TRUE;
14237 }
14238 ie += eLen;
14239 remLen -= eLen;
14240 }
14241 return FALSE;
14242}
14243
14244/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014245 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014246 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014247 * parameters during connect operation.
14248 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014249int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014250 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014251 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014252{
14253 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014254 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014255 ENTER();
14256
14257 /*set wpa version*/
14258 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14259
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014260 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014261 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014262 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014263 {
14264 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14265 }
14266 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14267 {
14268 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14269 }
14270 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014271
14272 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014273 pWextState->wpaVersion);
14274
14275 /*set authentication type*/
14276 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14277
14278 if (0 > status)
14279 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014280 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014281 "%s: failed to set authentication type ", __func__);
14282 return status;
14283 }
14284
14285 /*set key mgmt type*/
14286 if (req->crypto.n_akm_suites)
14287 {
14288 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14289 if (0 > status)
14290 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014291 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014292 __func__);
14293 return status;
14294 }
14295 }
14296
14297 /*set pairwise cipher type*/
14298 if (req->crypto.n_ciphers_pairwise)
14299 {
14300 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14301 req->crypto.ciphers_pairwise[0], true);
14302 if (0 > status)
14303 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014304 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014305 "%s: failed to set unicast cipher type", __func__);
14306 return status;
14307 }
14308 }
14309 else
14310 {
14311 /*Reset previous cipher suite to none*/
14312 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14313 if (0 > status)
14314 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014315 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014316 "%s: failed to set unicast cipher type", __func__);
14317 return status;
14318 }
14319 }
14320
14321 /*set group cipher type*/
14322 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14323 false);
14324
14325 if (0 > status)
14326 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014327 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014328 __func__);
14329 return status;
14330 }
14331
Chet Lanctot186b5732013-03-18 10:26:30 -070014332#ifdef WLAN_FEATURE_11W
14333 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14334#endif
14335
Jeff Johnson295189b2012-06-20 16:38:30 -070014336 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14337 if (req->ie_len)
14338 {
14339 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14340 if ( 0 > status)
14341 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014342 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014343 __func__);
14344 return status;
14345 }
14346 }
14347
14348 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014349 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014350 {
14351 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14352 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14353 )
14354 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014355 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014356 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14357 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014358 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014359 __func__);
14360 return -EOPNOTSUPP;
14361 }
14362 else
14363 {
14364 u8 key_len = req->key_len;
14365 u8 key_idx = req->key_idx;
14366
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014367 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014368 && (CSR_MAX_NUM_KEY > key_idx)
14369 )
14370 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014371 hddLog(VOS_TRACE_LEVEL_INFO,
14372 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014373 __func__, key_idx, key_len);
14374 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014375 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014376 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014377 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014378 (u8)key_len;
14379 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14380 }
14381 }
14382 }
14383 }
14384
14385 return status;
14386}
14387
14388/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014389 * FUNCTION: wlan_hdd_try_disconnect
14390 * This function is used to disconnect from previous
14391 * connection
14392 */
14393static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14394{
14395 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014396 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014397 hdd_station_ctx_t *pHddStaCtx;
14398 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014399 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014400
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014401 ret = wlan_hdd_validate_context(pHddCtx);
14402 if (0 != ret)
14403 {
14404 return ret;
14405 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014406 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14407
14408 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14409
14410 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14411 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053014412 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014413 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14414 {
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014415 spin_lock_bh(&pAdapter->lock_for_active_session);
14416 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14417 {
14418 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14419 }
14420 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053014421 hdd_connSetConnectionState(pHddStaCtx,
14422 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014423 /* Issue disconnect to CSR */
14424 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014425 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014426 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014427 eCSR_DISCONNECT_REASON_UNSPECIFIED);
14428 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
14429 hddLog(LOG1,
14430 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
14431 } else if ( 0 != status ) {
14432 hddLog(LOGE,
14433 FL("csrRoamDisconnect failure, returned %d"),
14434 (int)status );
14435 result = -EINVAL;
14436 goto disconnected;
14437 }
14438 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014439 &pAdapter->disconnect_comp_var,
14440 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014441 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
14442 hddLog(LOGE,
14443 "%s: Failed to disconnect, timed out", __func__);
14444 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014445 }
14446 }
14447 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14448 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014449 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014450 &pAdapter->disconnect_comp_var,
14451 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014452 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014453 {
14454 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014455 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014456 }
14457 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014458disconnected:
14459 hddLog(LOG1,
14460 FL("Set HDD connState to eConnectionState_NotConnected"));
14461 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14462 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014463}
14464
14465/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014466 * FUNCTION: __wlan_hdd_cfg80211_connect
14467 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014468 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014469static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014470 struct net_device *ndev,
14471 struct cfg80211_connect_params *req
14472 )
14473{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014474 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014475 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053014476#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
14477 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014478 const u8 *bssid_hint = req->bssid_hint;
14479#else
14480 const u8 *bssid_hint = NULL;
14481#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014482 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014483 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014484 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014485
14486 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014487
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014488 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14489 TRACE_CODE_HDD_CFG80211_CONNECT,
14490 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014491 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014492 "%s: device_mode = %s (%d)", __func__,
14493 hdd_device_modetoString(pAdapter->device_mode),
14494 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014495
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014496 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014497 if (!pHddCtx)
14498 {
14499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14500 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014501 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014502 }
14503
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014504 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014505 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014506 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014507 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014508 }
14509
Agarwal Ashish51325b52014-06-16 16:50:49 +053014510
Jeff Johnson295189b2012-06-20 16:38:30 -070014511#ifdef WLAN_BTAMP_FEATURE
14512 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014513 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014514 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014515 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014516 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014517 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014518 }
14519#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014520
14521 //If Device Mode is Station Concurrent Sessions Exit BMps
14522 //P2P Mode will be taken care in Open/close adapter
14523 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014524 (vos_concurrent_open_sessions_running())) {
14525 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14526 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014527 }
14528
14529 /*Try disconnecting if already in connected state*/
14530 status = wlan_hdd_try_disconnect(pAdapter);
14531 if ( 0 > status)
14532 {
14533 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14534 " connection"));
14535 return -EALREADY;
14536 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053014537 /* Check for max concurrent connections after doing disconnect if any*/
14538 if (vos_max_concurrent_connections_reached()) {
14539 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14540 return -ECONNREFUSED;
14541 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014542
Jeff Johnson295189b2012-06-20 16:38:30 -070014543 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014544 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014545
14546 if ( 0 > status)
14547 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014548 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014549 __func__);
14550 return status;
14551 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053014552
14553 if (pHddCtx->spoofMacAddr.isEnabled)
14554 {
14555 hddLog(VOS_TRACE_LEVEL_INFO,
14556 "%s: MAC Spoofing enabled ", __func__);
14557 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14558 * to fill TxBds for probe request during SSID scan which may happen
14559 * as part of connect command
14560 */
14561 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
14562 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
14563 if (status != VOS_STATUS_SUCCESS)
14564 return -ECONNREFUSED;
14565 }
14566
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014567 if (req->channel)
14568 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070014569 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014570 channel = 0;
14571 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14572 req->ssid_len, req->bssid,
14573 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014574
Sushant Kaushikd7083982015-03-18 14:33:24 +053014575 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014576 {
14577 //ReEnable BMPS if disabled
14578 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
14579 (NULL != pHddCtx))
14580 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053014581 if (pHddCtx->hdd_wlan_suspended)
14582 {
14583 hdd_set_pwrparams(pHddCtx);
14584 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014585 //ReEnable Bmps and Imps back
14586 hdd_enable_bmps_imps(pHddCtx);
14587 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014588 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070014589 return status;
14590 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014591 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014592 EXIT();
14593 return status;
14594}
14595
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014596static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
14597 struct net_device *ndev,
14598 struct cfg80211_connect_params *req)
14599{
14600 int ret;
14601 vos_ssr_protect(__func__);
14602 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
14603 vos_ssr_unprotect(__func__);
14604
14605 return ret;
14606}
Jeff Johnson295189b2012-06-20 16:38:30 -070014607
14608/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014609 * FUNCTION: wlan_hdd_disconnect
14610 * This function is used to issue a disconnect request to SME
14611 */
14612int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
14613{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014614 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014615 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014616 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014617 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014618
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014619 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014620
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014621 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014622 if (0 != status)
14623 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014624 return status;
14625 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053014626 /* Indicate sme of disconnect so that in progress connection or preauth
14627 * can be aborted
14628 */
14629 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053014630 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014631 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014632
Agarwal Ashish47d18112014-08-04 19:55:07 +053014633 /* Need to apply spin lock before decreasing active sessions
14634 * as there can be chance for double decrement if context switch
14635 * Calls hdd_DisConnectHandler.
14636 */
14637
14638 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014639 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14640 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014641 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14642 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053014643 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
14644 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014645
Abhishek Singhf4669da2014-05-26 15:07:49 +053014646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053014647 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
14648
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014649 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014650
Mihir Shete182a0b22014-08-18 16:08:48 +053014651 /*
14652 * stop tx queues before deleting STA/BSS context from the firmware.
14653 * tx has to be disabled because the firmware can get busy dropping
14654 * the tx frames after BSS/STA has been deleted and will not send
14655 * back a response resulting in WDI timeout
14656 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053014657 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053014658 netif_tx_disable(pAdapter->dev);
14659 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014660
Mihir Shete182a0b22014-08-18 16:08:48 +053014661 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014662 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14663 pAdapter->sessionId, reason);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014664 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
14665 {
14666 hddLog(LOG1,
14667 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014668 }
14669 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014670 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014671 hddLog(LOGE,
14672 FL("csrRoamDisconnect failure, returned %d"),
14673 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014674 result = -EINVAL;
14675 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014676 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014677 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014678 &pAdapter->disconnect_comp_var,
14679 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014680 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014681 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014682 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014683 "%s: Failed to disconnect, timed out", __func__);
Ratnam Rachuri38027182016-03-15 16:05:59 +053014684 VOS_BUG(0);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014685 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014686 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014687disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014688 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014689 FL("Set HDD connState to eConnectionState_NotConnected"));
14690 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14691
Abhishek Singh087de602015-10-21 17:18:55 +053014692#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
14693 /* Sending disconnect event to userspace for kernel version < 3.11
14694 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
14695 */
14696 hddLog(LOG1, FL("Send disconnected event to userspace"));
14697 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
14698 NULL, 0, GFP_KERNEL);
14699#endif
14700
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014701 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014702 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014703}
14704
14705
14706/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014707 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070014708 * This function is used to issue a disconnect request to SME
14709 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014710static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014711 struct net_device *dev,
14712 u16 reason
14713 )
14714{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014715 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014716 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014717 tCsrRoamProfile *pRoamProfile;
14718 hdd_station_ctx_t *pHddStaCtx;
14719 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014720#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014721 tANI_U8 staIdx;
14722#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014723
Jeff Johnson295189b2012-06-20 16:38:30 -070014724 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014725
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014726 if (!pAdapter) {
14727 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14728 return -EINVAL;
14729 }
14730
14731 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14732 if (!pHddStaCtx) {
14733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
14734 return -EINVAL;
14735 }
14736
14737 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14738 status = wlan_hdd_validate_context(pHddCtx);
14739 if (0 != status)
14740 {
14741 return status;
14742 }
14743
14744 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
14745
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014746 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14747 TRACE_CODE_HDD_CFG80211_DISCONNECT,
14748 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014749 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
14750 __func__, hdd_device_modetoString(pAdapter->device_mode),
14751 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014752
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014753 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
14754 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070014755
Jeff Johnson295189b2012-06-20 16:38:30 -070014756 if (NULL != pRoamProfile)
14757 {
14758 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014759 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
14760 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070014761 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014762 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070014763 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014764 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014765 switch(reason)
14766 {
14767 case WLAN_REASON_MIC_FAILURE:
14768 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
14769 break;
14770
14771 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
14772 case WLAN_REASON_DISASSOC_AP_BUSY:
14773 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
14774 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
14775 break;
14776
14777 case WLAN_REASON_PREV_AUTH_NOT_VALID:
14778 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053014779 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070014780 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
14781 break;
14782
Jeff Johnson295189b2012-06-20 16:38:30 -070014783 default:
14784 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
14785 break;
14786 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014787 pScanInfo = &pHddCtx->scan_info;
14788 if (pScanInfo->mScanPending)
14789 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014790 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014791 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014792 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014793 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014794 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053014795 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014796#ifdef FEATURE_WLAN_TDLS
14797 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014798 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014799 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014800 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
14801 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014802 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014803 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014804 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014806 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014807 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014808 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014809 status = sme_DeleteTdlsPeerSta(
14810 WLAN_HDD_GET_HAL_CTX(pAdapter),
14811 pAdapter->sessionId,
14812 mac);
14813 if (status != eHAL_STATUS_SUCCESS) {
14814 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
14815 return -EPERM;
14816 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014817 }
14818 }
14819#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014820 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014821 status = wlan_hdd_disconnect(pAdapter, reasonCode);
14822 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070014823 {
14824 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014825 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014826 __func__, (int)status );
14827 return -EINVAL;
14828 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014829 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014830 else
14831 {
14832 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
14833 "called while in %d state", __func__,
14834 pHddStaCtx->conn_info.connState);
14835 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014836 }
14837 else
14838 {
14839 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
14840 }
14841
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014842 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014843 return status;
14844}
14845
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014846static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
14847 struct net_device *dev,
14848 u16 reason
14849 )
14850{
14851 int ret;
14852 vos_ssr_protect(__func__);
14853 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
14854 vos_ssr_unprotect(__func__);
14855
14856 return ret;
14857}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014858
Jeff Johnson295189b2012-06-20 16:38:30 -070014859/*
14860 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014861 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014862 * settings in IBSS mode.
14863 */
14864static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014865 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014866 struct cfg80211_ibss_params *params
14867 )
14868{
14869 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014870 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014871 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14872 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014873
Jeff Johnson295189b2012-06-20 16:38:30 -070014874 ENTER();
14875
14876 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070014877 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070014878
14879 if (params->ie_len && ( NULL != params->ie) )
14880 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014881 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14882 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014883 {
14884 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14885 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14886 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014887 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014888 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014889 tDot11fIEWPA dot11WPAIE;
14890 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014891 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014892
Wilson Yang00256342013-10-10 23:13:38 -070014893 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014894 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14895 params->ie_len, DOT11F_EID_WPA);
14896 if ( NULL != ie )
14897 {
14898 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14899 // Unpack the WPA IE
14900 //Skip past the EID byte and length byte - and four byte WiFi OUI
14901 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
14902 &ie[2+4],
14903 ie[1] - 4,
14904 &dot11WPAIE);
14905 /*Extract the multicast cipher, the encType for unicast
14906 cipher for wpa-none is none*/
14907 encryptionType =
14908 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
14909 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014910 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014911
Jeff Johnson295189b2012-06-20 16:38:30 -070014912 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
14913
14914 if (0 > status)
14915 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014916 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014917 __func__);
14918 return status;
14919 }
14920 }
14921
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014922 pWextState->roamProfile.AuthType.authType[0] =
14923 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014924 eCSR_AUTH_TYPE_OPEN_SYSTEM;
14925
14926 if (params->privacy)
14927 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014928 /* Security enabled IBSS, At this time there is no information available
14929 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070014930 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014931 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070014932 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014933 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070014934 *enable privacy bit in beacons */
14935
14936 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
14937 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014938 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
14939 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070014940 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14941 pWextState->roamProfile.EncryptionType.numEntries = 1;
14942 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070014943 return status;
14944}
14945
14946/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014947 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014948 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070014949 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014950static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014951 struct net_device *dev,
14952 struct cfg80211_ibss_params *params
14953 )
14954{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014955 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014956 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14957 tCsrRoamProfile *pRoamProfile;
14958 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014959 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14960 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014961 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070014962
14963 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014964
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014965 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14966 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
14967 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014968 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014969 "%s: device_mode = %s (%d)", __func__,
14970 hdd_device_modetoString(pAdapter->device_mode),
14971 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014972
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014973 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014974 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014975 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014976 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014977 }
14978
14979 if (NULL == pWextState)
14980 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014981 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070014982 __func__);
14983 return -EIO;
14984 }
14985
Agarwal Ashish51325b52014-06-16 16:50:49 +053014986 if (vos_max_concurrent_connections_reached()) {
14987 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14988 return -ECONNREFUSED;
14989 }
14990
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014991 /*Try disconnecting if already in connected state*/
14992 status = wlan_hdd_try_disconnect(pAdapter);
14993 if ( 0 > status)
14994 {
14995 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14996 " IBSS connection"));
14997 return -EALREADY;
14998 }
14999
Jeff Johnson295189b2012-06-20 16:38:30 -070015000 pRoamProfile = &pWextState->roamProfile;
15001
15002 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
15003 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015004 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015005 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015006 return -EINVAL;
15007 }
15008
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015009 /* BSSID is provided by upper layers hence no need to AUTO generate */
15010 if (NULL != params->bssid) {
15011 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15012 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
15013 hddLog (VOS_TRACE_LEVEL_ERROR,
15014 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15015 return -EIO;
15016 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015017 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015018 }
krunal sonie9002db2013-11-25 14:24:17 -080015019 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
15020 {
15021 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15022 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
15023 {
15024 hddLog (VOS_TRACE_LEVEL_ERROR,
15025 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15026 return -EIO;
15027 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015028
15029 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080015030 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015031 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080015032 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015033
Jeff Johnson295189b2012-06-20 16:38:30 -070015034 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070015035 if (NULL !=
15036#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15037 params->chandef.chan)
15038#else
15039 params->channel)
15040#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015041 {
15042 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015043 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15044 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
15045 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15046 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015047
15048 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015049 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070015050 ieee80211_frequency_to_channel(
15051#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15052 params->chandef.chan->center_freq);
15053#else
15054 params->channel->center_freq);
15055#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015056
15057 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15058 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070015059 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015060 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
15061 __func__);
15062 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070015063 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015064
15065 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015066 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015067 if (channelNum == validChan[indx])
15068 {
15069 break;
15070 }
15071 }
15072 if (indx >= numChans)
15073 {
15074 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015075 __func__, channelNum);
15076 return -EINVAL;
15077 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015078 /* Set the Operational Channel */
15079 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
15080 channelNum);
15081 pRoamProfile->ChannelInfo.numOfChannels = 1;
15082 pHddStaCtx->conn_info.operationChannel = channelNum;
15083 pRoamProfile->ChannelInfo.ChannelList =
15084 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070015085 }
15086
15087 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015088 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070015089 if (status < 0)
15090 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015091 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070015092 __func__);
15093 return status;
15094 }
15095
15096 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015097 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053015098 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015099 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015100
15101 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015102 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015103
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015104 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015105 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015106}
15107
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015108static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
15109 struct net_device *dev,
15110 struct cfg80211_ibss_params *params
15111 )
15112{
15113 int ret = 0;
15114
15115 vos_ssr_protect(__func__);
15116 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15117 vos_ssr_unprotect(__func__);
15118
15119 return ret;
15120}
15121
Jeff Johnson295189b2012-06-20 16:38:30 -070015122/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015123 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015124 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015125 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015126static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015127 struct net_device *dev
15128 )
15129{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015130 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015131 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15132 tCsrRoamProfile *pRoamProfile;
15133 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015134 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015135
15136 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015137
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015138 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15139 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15140 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015141 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015142 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015143 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015144 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015145 }
15146
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015147 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15148 hdd_device_modetoString(pAdapter->device_mode),
15149 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015150 if (NULL == pWextState)
15151 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015152 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015153 __func__);
15154 return -EIO;
15155 }
15156
15157 pRoamProfile = &pWextState->roamProfile;
15158
15159 /* Issue disconnect only if interface type is set to IBSS */
15160 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15161 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015162 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015163 __func__);
15164 return -EINVAL;
15165 }
15166
15167 /* Issue Disconnect request */
15168 INIT_COMPLETION(pAdapter->disconnect_comp_var);
15169 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15170 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15171
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015172 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015173 return 0;
15174}
15175
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015176static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15177 struct net_device *dev
15178 )
15179{
15180 int ret = 0;
15181
15182 vos_ssr_protect(__func__);
15183 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15184 vos_ssr_unprotect(__func__);
15185
15186 return ret;
15187}
15188
Jeff Johnson295189b2012-06-20 16:38:30 -070015189/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015190 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015191 * This function is used to set the phy parameters
15192 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15193 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015194static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015195 u32 changed)
15196{
15197 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15198 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015199 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015200
15201 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015202
15203 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015204 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15205 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015206
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015207 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015208 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015209 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015210 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015211 }
15212
Jeff Johnson295189b2012-06-20 16:38:30 -070015213 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15214 {
15215 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15216 WNI_CFG_RTS_THRESHOLD_STAMAX :
15217 wiphy->rts_threshold;
15218
15219 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015220 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015221 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015222 hddLog(VOS_TRACE_LEVEL_ERROR,
15223 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015224 __func__, rts_threshold);
15225 return -EINVAL;
15226 }
15227
15228 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15229 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015230 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015231 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015232 hddLog(VOS_TRACE_LEVEL_ERROR,
15233 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015234 __func__, rts_threshold);
15235 return -EIO;
15236 }
15237
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015238 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015239 rts_threshold);
15240 }
15241
15242 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15243 {
15244 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15245 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15246 wiphy->frag_threshold;
15247
15248 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015249 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015250 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015251 hddLog(VOS_TRACE_LEVEL_ERROR,
15252 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015253 frag_threshold);
15254 return -EINVAL;
15255 }
15256
15257 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15258 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015259 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015260 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015261 hddLog(VOS_TRACE_LEVEL_ERROR,
15262 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015263 __func__, frag_threshold);
15264 return -EIO;
15265 }
15266
15267 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15268 frag_threshold);
15269 }
15270
15271 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15272 || (changed & WIPHY_PARAM_RETRY_LONG))
15273 {
15274 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15275 wiphy->retry_short :
15276 wiphy->retry_long;
15277
15278 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15279 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15280 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015281 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015282 __func__, retry_value);
15283 return -EINVAL;
15284 }
15285
15286 if (changed & WIPHY_PARAM_RETRY_SHORT)
15287 {
15288 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15289 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015290 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015291 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015292 hddLog(VOS_TRACE_LEVEL_ERROR,
15293 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015294 __func__, retry_value);
15295 return -EIO;
15296 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015297 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015298 __func__, retry_value);
15299 }
15300 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15301 {
15302 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15303 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015304 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015305 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015306 hddLog(VOS_TRACE_LEVEL_ERROR,
15307 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015308 __func__, retry_value);
15309 return -EIO;
15310 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015311 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015312 __func__, retry_value);
15313 }
15314 }
15315
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015316 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015317 return 0;
15318}
15319
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015320static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15321 u32 changed)
15322{
15323 int ret;
15324
15325 vos_ssr_protect(__func__);
15326 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15327 vos_ssr_unprotect(__func__);
15328
15329 return ret;
15330}
15331
Jeff Johnson295189b2012-06-20 16:38:30 -070015332/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015333 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015334 * This function is used to set the txpower
15335 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015336static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015337#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15338 struct wireless_dev *wdev,
15339#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015340#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015341 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015342#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015343 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015344#endif
15345 int dbm)
15346{
15347 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015348 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015349 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15350 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015351 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015352
15353 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015354
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015355 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15356 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15357 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015358 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015359 if (0 != status)
15360 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015361 return status;
15362 }
15363
15364 hHal = pHddCtx->hHal;
15365
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015366 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15367 dbm, ccmCfgSetCallback,
15368 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015369 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015370 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015371 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15372 return -EIO;
15373 }
15374
15375 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15376 dbm);
15377
15378 switch(type)
15379 {
15380 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15381 /* Fall through */
15382 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15383 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15384 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015385 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15386 __func__);
15387 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015388 }
15389 break;
15390 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015391 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015392 __func__);
15393 return -EOPNOTSUPP;
15394 break;
15395 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015396 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15397 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015398 return -EIO;
15399 }
15400
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015401 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015402 return 0;
15403}
15404
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015405static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15406#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15407 struct wireless_dev *wdev,
15408#endif
15409#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15410 enum tx_power_setting type,
15411#else
15412 enum nl80211_tx_power_setting type,
15413#endif
15414 int dbm)
15415{
15416 int ret;
15417 vos_ssr_protect(__func__);
15418 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15419#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15420 wdev,
15421#endif
15422#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15423 type,
15424#else
15425 type,
15426#endif
15427 dbm);
15428 vos_ssr_unprotect(__func__);
15429
15430 return ret;
15431}
15432
Jeff Johnson295189b2012-06-20 16:38:30 -070015433/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015434 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015435 * This function is used to read the txpower
15436 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015437static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015438#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15439 struct wireless_dev *wdev,
15440#endif
15441 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015442{
15443
15444 hdd_adapter_t *pAdapter;
15445 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015446 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015447
Jeff Johnsone7245742012-09-05 17:12:55 -070015448 ENTER();
15449
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015450 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015451 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015452 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015453 *dbm = 0;
15454 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015455 }
15456
Jeff Johnson295189b2012-06-20 16:38:30 -070015457 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15458 if (NULL == pAdapter)
15459 {
15460 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15461 return -ENOENT;
15462 }
15463
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015464 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15465 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15466 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015467 wlan_hdd_get_classAstats(pAdapter);
15468 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15469
Jeff Johnsone7245742012-09-05 17:12:55 -070015470 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015471 return 0;
15472}
15473
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015474static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15475#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15476 struct wireless_dev *wdev,
15477#endif
15478 int *dbm)
15479{
15480 int ret;
15481
15482 vos_ssr_protect(__func__);
15483 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15484#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15485 wdev,
15486#endif
15487 dbm);
15488 vos_ssr_unprotect(__func__);
15489
15490 return ret;
15491}
15492
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015493static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015494#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15495 const u8* mac,
15496#else
15497 u8* mac,
15498#endif
15499 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015500{
15501 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15502 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15503 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053015504 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015505
15506 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
15507 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070015508
15509 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
15510 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
15511 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
15512 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
15513 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
15514 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
15515 tANI_U16 maxRate = 0;
15516 tANI_U16 myRate;
15517 tANI_U16 currentRate = 0;
15518 tANI_U8 maxSpeedMCS = 0;
15519 tANI_U8 maxMCSIdx = 0;
15520 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053015521 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070015522 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015523 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015524
Leo Chang6f8870f2013-03-26 18:11:36 -070015525#ifdef WLAN_FEATURE_11AC
15526 tANI_U32 vht_mcs_map;
15527 eDataRate11ACMaxMcs vhtMaxMcs;
15528#endif /* WLAN_FEATURE_11AC */
15529
Jeff Johnsone7245742012-09-05 17:12:55 -070015530 ENTER();
15531
Jeff Johnson295189b2012-06-20 16:38:30 -070015532 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15533 (0 == ssidlen))
15534 {
15535 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
15536 " Invalid ssidlen, %d", __func__, ssidlen);
15537 /*To keep GUI happy*/
15538 return 0;
15539 }
15540
Mukul Sharma811205f2014-07-09 21:07:30 +053015541 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
15542 {
15543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15544 "%s: Roaming in progress, so unable to proceed this request", __func__);
15545 return 0;
15546 }
15547
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015548 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015549 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015550 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015551 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015552 }
15553
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053015554 wlan_hdd_get_station_stats(pAdapter);
15555 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015556
Kiet Lam3b17fc82013-09-27 05:24:08 +053015557 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
15558 sinfo->filled |= STATION_INFO_SIGNAL;
15559
c_hpothu09f19542014-05-30 21:53:31 +053015560 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053015561 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
15562 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053015563 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053015564 {
15565 rate_flags = pAdapter->maxRateFlags;
15566 }
c_hpothu44ff4e02014-05-08 00:13:57 +053015567
Jeff Johnson295189b2012-06-20 16:38:30 -070015568 //convert to the UI units of 100kbps
15569 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
15570
15571#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070015572 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 -070015573 sinfo->signal,
15574 pCfg->reportMaxLinkSpeed,
15575 myRate,
15576 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015577 (int) pCfg->linkSpeedRssiMid,
15578 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070015579 (int) rate_flags,
15580 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070015581#endif //LINKSPEED_DEBUG_ENABLED
15582
15583 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
15584 {
15585 // we do not want to necessarily report the current speed
15586 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
15587 {
15588 // report the max possible speed
15589 rssidx = 0;
15590 }
15591 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
15592 {
15593 // report the max possible speed with RSSI scaling
15594 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
15595 {
15596 // report the max possible speed
15597 rssidx = 0;
15598 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015599 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070015600 {
15601 // report middle speed
15602 rssidx = 1;
15603 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015604 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
15605 {
15606 // report middle speed
15607 rssidx = 2;
15608 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015609 else
15610 {
15611 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015612 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070015613 }
15614 }
15615 else
15616 {
15617 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
15618 hddLog(VOS_TRACE_LEVEL_ERROR,
15619 "%s: Invalid value for reportMaxLinkSpeed: %u",
15620 __func__, pCfg->reportMaxLinkSpeed);
15621 rssidx = 0;
15622 }
15623
15624 maxRate = 0;
15625
15626 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015627 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
15628 OperationalRates, &ORLeng))
15629 {
15630 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15631 /*To keep GUI happy*/
15632 return 0;
15633 }
15634
Jeff Johnson295189b2012-06-20 16:38:30 -070015635 for (i = 0; i < ORLeng; i++)
15636 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015637 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015638 {
15639 /* Validate Rate Set */
15640 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
15641 {
15642 currentRate = supported_data_rate[j].supported_rate[rssidx];
15643 break;
15644 }
15645 }
15646 /* Update MAX rate */
15647 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15648 }
15649
15650 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015651 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
15652 ExtendedRates, &ERLeng))
15653 {
15654 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15655 /*To keep GUI happy*/
15656 return 0;
15657 }
15658
Jeff Johnson295189b2012-06-20 16:38:30 -070015659 for (i = 0; i < ERLeng; i++)
15660 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015661 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015662 {
15663 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
15664 {
15665 currentRate = supported_data_rate[j].supported_rate[rssidx];
15666 break;
15667 }
15668 }
15669 /* Update MAX rate */
15670 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15671 }
c_hpothu79aab322014-07-14 21:11:01 +053015672
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015673 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053015674 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015675 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053015676 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070015677 {
c_hpothu79aab322014-07-14 21:11:01 +053015678 if (rate_flags & eHAL_TX_RATE_VHT80)
15679 mode = 2;
15680 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
15681 mode = 1;
15682 else
15683 mode = 0;
15684
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015685 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
15686 MCSRates, &MCSLeng))
15687 {
15688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15689 /*To keep GUI happy*/
15690 return 0;
15691 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015692 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070015693#ifdef WLAN_FEATURE_11AC
15694 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015695 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070015696 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015697 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015698 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070015699 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070015700 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015701 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015702 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015703 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070015704 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015705 maxMCSIdx = 7;
15706 }
15707 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
15708 {
15709 maxMCSIdx = 8;
15710 }
15711 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
15712 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015713 //VHT20 is supporting 0~8
15714 if (rate_flags & eHAL_TX_RATE_VHT20)
15715 maxMCSIdx = 8;
15716 else
15717 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070015718 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015719
c_hpothu79aab322014-07-14 21:11:01 +053015720 if (0 != rssidx)/*check for scaled */
15721 {
15722 //get middle rate MCS index if rssi=1/2
15723 for (i=0; i <= maxMCSIdx; i++)
15724 {
15725 if (sinfo->signal <= rssiMcsTbl[mode][i])
15726 {
15727 maxMCSIdx = i;
15728 break;
15729 }
15730 }
15731 }
15732
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015733 if (rate_flags & eHAL_TX_RATE_VHT80)
15734 {
15735 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
15736 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
15737 }
15738 else if (rate_flags & eHAL_TX_RATE_VHT40)
15739 {
15740 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
15741 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
15742 }
15743 else if (rate_flags & eHAL_TX_RATE_VHT20)
15744 {
15745 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
15746 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
15747 }
15748
Leo Chang6f8870f2013-03-26 18:11:36 -070015749 maxSpeedMCS = 1;
15750 if (currentRate > maxRate)
15751 {
15752 maxRate = currentRate;
15753 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015754
Leo Chang6f8870f2013-03-26 18:11:36 -070015755 }
15756 else
15757#endif /* WLAN_FEATURE_11AC */
15758 {
15759 if (rate_flags & eHAL_TX_RATE_HT40)
15760 {
15761 rateFlag |= 1;
15762 }
15763 if (rate_flags & eHAL_TX_RATE_SGI)
15764 {
15765 rateFlag |= 2;
15766 }
15767
Girish Gowli01abcee2014-07-31 20:18:55 +053015768 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053015769 if (rssidx == 1 || rssidx == 2)
15770 {
15771 //get middle rate MCS index if rssi=1/2
15772 for (i=0; i <= 7; i++)
15773 {
15774 if (sinfo->signal <= rssiMcsTbl[mode][i])
15775 {
15776 temp = i+1;
15777 break;
15778 }
15779 }
15780 }
c_hpothu79aab322014-07-14 21:11:01 +053015781
15782 for (i = 0; i < MCSLeng; i++)
15783 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015784 for (j = 0; j < temp; j++)
15785 {
15786 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
15787 {
15788 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015789 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015790 break;
15791 }
15792 }
15793 if ((j < temp) && (currentRate > maxRate))
15794 {
15795 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070015796 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015797 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015798 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015799 }
15800 }
15801
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015802 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
15803 {
15804 maxRate = myRate;
15805 maxSpeedMCS = 1;
15806 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15807 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015808 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053015809 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070015810 {
15811 maxRate = myRate;
15812 if (rate_flags & eHAL_TX_RATE_LEGACY)
15813 {
15814 maxSpeedMCS = 0;
15815 }
15816 else
15817 {
15818 maxSpeedMCS = 1;
15819 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15820 }
15821 }
15822
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015823 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070015824 {
15825 sinfo->txrate.legacy = maxRate;
15826#ifdef LINKSPEED_DEBUG_ENABLED
15827 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
15828#endif //LINKSPEED_DEBUG_ENABLED
15829 }
15830 else
15831 {
15832 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070015833#ifdef WLAN_FEATURE_11AC
15834 sinfo->txrate.nss = 1;
15835 if (rate_flags & eHAL_TX_RATE_VHT80)
15836 {
15837 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015838 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070015839 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015840 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070015841 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015842 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15843 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15844 }
15845 else if (rate_flags & eHAL_TX_RATE_VHT20)
15846 {
15847 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15848 }
15849#endif /* WLAN_FEATURE_11AC */
15850 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
15851 {
15852 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15853 if (rate_flags & eHAL_TX_RATE_HT40)
15854 {
15855 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15856 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015857 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015858 if (rate_flags & eHAL_TX_RATE_SGI)
15859 {
15860 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15861 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015862
Jeff Johnson295189b2012-06-20 16:38:30 -070015863#ifdef LINKSPEED_DEBUG_ENABLED
15864 pr_info("Reporting MCS rate %d flags %x\n",
15865 sinfo->txrate.mcs,
15866 sinfo->txrate.flags );
15867#endif //LINKSPEED_DEBUG_ENABLED
15868 }
15869 }
15870 else
15871 {
15872 // report current rate instead of max rate
15873
15874 if (rate_flags & eHAL_TX_RATE_LEGACY)
15875 {
15876 //provide to the UI in units of 100kbps
15877 sinfo->txrate.legacy = myRate;
15878#ifdef LINKSPEED_DEBUG_ENABLED
15879 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
15880#endif //LINKSPEED_DEBUG_ENABLED
15881 }
15882 else
15883 {
15884 //must be MCS
15885 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015886#ifdef WLAN_FEATURE_11AC
15887 sinfo->txrate.nss = 1;
15888 if (rate_flags & eHAL_TX_RATE_VHT80)
15889 {
15890 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15891 }
15892 else
15893#endif /* WLAN_FEATURE_11AC */
15894 {
15895 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15896 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015897 if (rate_flags & eHAL_TX_RATE_SGI)
15898 {
15899 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15900 }
15901 if (rate_flags & eHAL_TX_RATE_HT40)
15902 {
15903 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15904 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015905#ifdef WLAN_FEATURE_11AC
15906 else if (rate_flags & eHAL_TX_RATE_VHT80)
15907 {
15908 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
15909 }
15910#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070015911#ifdef LINKSPEED_DEBUG_ENABLED
15912 pr_info("Reporting actual MCS rate %d flags %x\n",
15913 sinfo->txrate.mcs,
15914 sinfo->txrate.flags );
15915#endif //LINKSPEED_DEBUG_ENABLED
15916 }
15917 }
15918 sinfo->filled |= STATION_INFO_TX_BITRATE;
15919
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070015920 sinfo->tx_packets =
15921 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
15922 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
15923 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
15924 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
15925
15926 sinfo->tx_retries =
15927 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
15928 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
15929 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
15930 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
15931
15932 sinfo->tx_failed =
15933 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
15934 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
15935 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
15936 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
15937
15938 sinfo->filled |=
15939 STATION_INFO_TX_PACKETS |
15940 STATION_INFO_TX_RETRIES |
15941 STATION_INFO_TX_FAILED;
15942
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053015943 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
15944 sinfo->filled |= STATION_INFO_RX_PACKETS;
15945
15946 if (rate_flags & eHAL_TX_RATE_LEGACY)
15947 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
15948 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
15949 sinfo->rx_packets);
15950 else
15951 hddLog(LOG1,
15952 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
15953 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
15954 sinfo->tx_packets, sinfo->rx_packets);
15955
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015956 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15957 TRACE_CODE_HDD_CFG80211_GET_STA,
15958 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070015959 EXIT();
15960 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015961}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015962#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15963static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
15964 const u8* mac, struct station_info *sinfo)
15965#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015966static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
15967 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015968#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015969{
15970 int ret;
15971
15972 vos_ssr_protect(__func__);
15973 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
15974 vos_ssr_unprotect(__func__);
15975
15976 return ret;
15977}
15978
15979static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070015980 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070015981{
15982 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015983 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015984 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015985 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015986
Jeff Johnsone7245742012-09-05 17:12:55 -070015987 ENTER();
15988
Jeff Johnson295189b2012-06-20 16:38:30 -070015989 if (NULL == pAdapter)
15990 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015991 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015992 return -ENODEV;
15993 }
15994
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015995 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15996 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
15997 pAdapter->sessionId, timeout));
15998
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015999 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016000 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016001 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016002 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016003 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016004 }
16005
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016006 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
16007 (TRUE == pHddCtx->hdd_wlan_suspended) &&
16008 (pHddCtx->cfg_ini->fhostArpOffload) &&
16009 (eConnectionState_Associated ==
16010 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
16011 {
Amar Singhald53568e2013-09-26 11:03:45 -070016012
16013 hddLog(VOS_TRACE_LEVEL_INFO,
16014 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053016015 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016016 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16017 {
16018 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016019 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016020 __func__, vos_status);
16021 }
16022 }
16023
Jeff Johnson295189b2012-06-20 16:38:30 -070016024 /**The get power cmd from the supplicant gets updated by the nl only
16025 *on successful execution of the function call
16026 *we are oppositely mapped w.r.t mode in the driver
16027 **/
16028 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
16029
16030 if (VOS_STATUS_E_FAILURE == vos_status)
16031 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016032 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16033 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016034 return -EINVAL;
16035 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016036 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016037 return 0;
16038}
16039
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016040static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
16041 struct net_device *dev, bool mode, int timeout)
16042{
16043 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016044
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016045 vos_ssr_protect(__func__);
16046 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
16047 vos_ssr_unprotect(__func__);
16048
16049 return ret;
16050}
Sushant Kaushik084f6592015-09-10 13:11:56 +053016051
Jeff Johnson295189b2012-06-20 16:38:30 -070016052#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016053static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
16054 struct net_device *netdev,
16055 u8 key_index)
16056{
16057 ENTER();
16058 return 0;
16059}
16060
Jeff Johnson295189b2012-06-20 16:38:30 -070016061static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016062 struct net_device *netdev,
16063 u8 key_index)
16064{
16065 int ret;
16066 vos_ssr_protect(__func__);
16067 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
16068 vos_ssr_unprotect(__func__);
16069 return ret;
16070}
16071#endif //LINUX_VERSION_CODE
16072
16073#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16074static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16075 struct net_device *dev,
16076 struct ieee80211_txq_params *params)
16077{
16078 ENTER();
16079 return 0;
16080}
16081#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16082static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16083 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016084{
Jeff Johnsone7245742012-09-05 17:12:55 -070016085 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070016086 return 0;
16087}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016088#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070016089
16090#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16091static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016092 struct net_device *dev,
16093 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016094{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016095 int ret;
16096
16097 vos_ssr_protect(__func__);
16098 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
16099 vos_ssr_unprotect(__func__);
16100 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016101}
16102#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16103static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
16104 struct ieee80211_txq_params *params)
16105{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016106 int ret;
16107
16108 vos_ssr_protect(__func__);
16109 ret = __wlan_hdd_set_txq_params(wiphy, params);
16110 vos_ssr_unprotect(__func__);
16111 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016112}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016113#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016114
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016115static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016116 struct net_device *dev,
16117 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070016118{
16119 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016120 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016121 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016122 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016123 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016124 v_CONTEXT_t pVosContext = NULL;
16125 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016126
Jeff Johnsone7245742012-09-05 17:12:55 -070016127 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016128
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016129 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016130 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016131 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016132 return -EINVAL;
16133 }
16134
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016135 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16136 TRACE_CODE_HDD_CFG80211_DEL_STA,
16137 pAdapter->sessionId, pAdapter->device_mode));
16138
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016139 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16140 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016141 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016142 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016143 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016144 }
16145
Jeff Johnson295189b2012-06-20 16:38:30 -070016146 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016147 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016148 )
16149 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016150 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16151 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16152 if(pSapCtx == NULL){
16153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16154 FL("psapCtx is NULL"));
16155 return -ENOENT;
16156 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016157 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016158 {
16159 v_U16_t i;
16160 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16161 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016162 if ((pSapCtx->aStaInfo[i].isUsed) &&
16163 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016164 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016165 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016166 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016167 ETHER_ADDR_LEN);
16168
Jeff Johnson295189b2012-06-20 16:38:30 -070016169 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016170 "%s: Delete STA with MAC::"
16171 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016172 __func__,
16173 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16174 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016175 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016176 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016177 }
16178 }
16179 }
16180 else
16181 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016182
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016183 vos_status = hdd_softap_GetStaId(pAdapter,
16184 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016185 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16186 {
16187 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016188 "%s: Skip this DEL STA as this is not used::"
16189 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016190 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016191 return -ENOENT;
16192 }
16193
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016194 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016195 {
16196 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016197 "%s: Skip this DEL STA as deauth is in progress::"
16198 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016199 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016200 return -ENOENT;
16201 }
16202
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016203 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016204
Jeff Johnson295189b2012-06-20 16:38:30 -070016205 hddLog(VOS_TRACE_LEVEL_INFO,
16206 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016207 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016208 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016209 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016210
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016211 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016212 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16213 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016214 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016215 hddLog(VOS_TRACE_LEVEL_INFO,
16216 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016217 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016218 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016219 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016220 return -ENOENT;
16221 }
16222
Jeff Johnson295189b2012-06-20 16:38:30 -070016223 }
16224 }
16225
16226 EXIT();
16227
16228 return 0;
16229}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016230
16231#ifdef CFG80211_DEL_STA_V2
16232static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16233 struct net_device *dev,
16234 struct station_del_parameters *param)
16235#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016236#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16237static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16238 struct net_device *dev, const u8 *mac)
16239#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016240static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16241 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016242#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016243#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016244{
16245 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016246 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016247
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016248 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016249
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016250#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016251 if (NULL == param) {
16252 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016253 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016254 return -EINVAL;
16255 }
16256
16257 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16258 param->subtype, &delStaParams);
16259
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016260#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016261 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016262 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016263#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016264 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16265
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016266 vos_ssr_unprotect(__func__);
16267
16268 return ret;
16269}
16270
16271static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016272 struct net_device *dev,
16273#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16274 const u8 *mac,
16275#else
16276 u8 *mac,
16277#endif
16278 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016279{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016280 hdd_adapter_t *pAdapter;
16281 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016282 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016283#ifdef FEATURE_WLAN_TDLS
16284 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016285
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016286 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016287
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016288 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16289 if (NULL == pAdapter)
16290 {
16291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16292 "%s: Adapter is NULL",__func__);
16293 return -EINVAL;
16294 }
16295 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16296 status = wlan_hdd_validate_context(pHddCtx);
16297 if (0 != status)
16298 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016299 return status;
16300 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016301
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016302 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16303 TRACE_CODE_HDD_CFG80211_ADD_STA,
16304 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016305 mask = params->sta_flags_mask;
16306
16307 set = params->sta_flags_set;
16308
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016310 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16311 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016312
16313 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16314 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016315 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016316 }
16317 }
16318#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016319 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016320 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016321}
16322
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016323#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16324static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16325 struct net_device *dev, const u8 *mac,
16326 struct station_parameters *params)
16327#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016328static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16329 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016330#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016331{
16332 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016333
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016334 vos_ssr_protect(__func__);
16335 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16336 vos_ssr_unprotect(__func__);
16337
16338 return ret;
16339}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016340#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016341
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016342static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016343 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016344{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016345 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16346 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016347 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016348 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016349 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016350 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016351
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016352 ENTER();
16353
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016354 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016355 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016356 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016357 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016358 return -EINVAL;
16359 }
16360
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016361 if (!pmksa) {
16362 hddLog(LOGE, FL("pmksa is NULL"));
16363 return -EINVAL;
16364 }
16365
16366 if (!pmksa->bssid || !pmksa->pmkid) {
16367 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16368 pmksa->bssid, pmksa->pmkid);
16369 return -EINVAL;
16370 }
16371
16372 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16373 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16374
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016375 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16376 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016377 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016378 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016379 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016380 }
16381
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016382 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016383 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16384
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016385 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16386 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016387
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016388 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016389 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016390 &pmk_id, 1, FALSE);
16391
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016392 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16393 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16394 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016395
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016396 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016397 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016398}
16399
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016400static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16401 struct cfg80211_pmksa *pmksa)
16402{
16403 int ret;
16404
16405 vos_ssr_protect(__func__);
16406 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16407 vos_ssr_unprotect(__func__);
16408
16409 return ret;
16410}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016411
Wilson Yang6507c4e2013-10-01 20:11:19 -070016412
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016413static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016414 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016415{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016416 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16417 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016418 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016419 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016420
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016421 ENTER();
16422
Wilson Yang6507c4e2013-10-01 20:11:19 -070016423 /* Validate pAdapter */
16424 if (NULL == pAdapter)
16425 {
16426 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16427 return -EINVAL;
16428 }
16429
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016430 if (!pmksa) {
16431 hddLog(LOGE, FL("pmksa is NULL"));
16432 return -EINVAL;
16433 }
16434
16435 if (!pmksa->bssid) {
16436 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16437 return -EINVAL;
16438 }
16439
Kiet Lam98c46a12014-10-31 15:34:57 -070016440 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16441 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16442
Wilson Yang6507c4e2013-10-01 20:11:19 -070016443 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16444 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016445 if (0 != status)
16446 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016447 return status;
16448 }
16449
16450 /*Retrieve halHandle*/
16451 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16452
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016453 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16454 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16455 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016456 /* Delete the PMKID CSR cache */
16457 if (eHAL_STATUS_SUCCESS !=
16458 sme_RoamDelPMKIDfromCache(halHandle,
16459 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16460 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16461 MAC_ADDR_ARRAY(pmksa->bssid));
16462 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016463 }
16464
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016465 EXIT();
16466 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016467}
16468
Wilson Yang6507c4e2013-10-01 20:11:19 -070016469
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016470static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16471 struct cfg80211_pmksa *pmksa)
16472{
16473 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016474
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016475 vos_ssr_protect(__func__);
16476 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16477 vos_ssr_unprotect(__func__);
16478
16479 return ret;
16480
16481}
16482
16483static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016484{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016485 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16486 tHalHandle halHandle;
16487 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016488 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016489
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016490 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016491
16492 /* Validate pAdapter */
16493 if (NULL == pAdapter)
16494 {
16495 hddLog(VOS_TRACE_LEVEL_ERROR,
16496 "%s: Invalid Adapter" ,__func__);
16497 return -EINVAL;
16498 }
16499
16500 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16501 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016502 if (0 != status)
16503 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016504 return status;
16505 }
16506
16507 /*Retrieve halHandle*/
16508 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16509
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016510 /* Flush the PMKID cache in CSR */
16511 if (eHAL_STATUS_SUCCESS !=
16512 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
16513 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
16514 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016515 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016516 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080016517 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016518}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016519
16520static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
16521{
16522 int ret;
16523
16524 vos_ssr_protect(__func__);
16525 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
16526 vos_ssr_unprotect(__func__);
16527
16528 return ret;
16529}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016530#endif
16531
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016532#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016533static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16534 struct net_device *dev,
16535 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016536{
16537 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16538 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016539 hdd_context_t *pHddCtx;
16540 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016541
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016542 ENTER();
16543
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016544 if (NULL == pAdapter)
16545 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016546 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016547 return -ENODEV;
16548 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016549 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16550 ret = wlan_hdd_validate_context(pHddCtx);
16551 if (0 != ret)
16552 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016553 return ret;
16554 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016555 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016556 if (NULL == pHddStaCtx)
16557 {
16558 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
16559 return -EINVAL;
16560 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016561
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016562 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16563 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
16564 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016565 // Added for debug on reception of Re-assoc Req.
16566 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
16567 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016568 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016569 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080016570 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016571 }
16572
16573#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080016574 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016575 ftie->ie_len);
16576#endif
16577
16578 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016579 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
16580 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016581 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016582
16583 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016584 return 0;
16585}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016586
16587static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16588 struct net_device *dev,
16589 struct cfg80211_update_ft_ies_params *ftie)
16590{
16591 int ret;
16592
16593 vos_ssr_protect(__func__);
16594 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
16595 vos_ssr_unprotect(__func__);
16596
16597 return ret;
16598}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016599#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016600
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016601#ifdef FEATURE_WLAN_SCAN_PNO
16602
16603void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
16604 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
16605{
16606 int ret;
16607 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
16608 hdd_context_t *pHddCtx;
16609
Nirav Shah80830bf2013-12-31 16:35:12 +053016610 ENTER();
16611
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016612 if (NULL == pAdapter)
16613 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016615 "%s: HDD adapter is Null", __func__);
16616 return ;
16617 }
16618
16619 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16620 if (NULL == pHddCtx)
16621 {
16622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16623 "%s: HDD context is Null!!!", __func__);
16624 return ;
16625 }
16626
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016627 spin_lock(&pHddCtx->schedScan_lock);
16628 if (TRUE == pHddCtx->isWiphySuspended)
16629 {
16630 pHddCtx->isSchedScanUpdatePending = TRUE;
16631 spin_unlock(&pHddCtx->schedScan_lock);
16632 hddLog(VOS_TRACE_LEVEL_INFO,
16633 "%s: Update cfg80211 scan database after it resume", __func__);
16634 return ;
16635 }
16636 spin_unlock(&pHddCtx->schedScan_lock);
16637
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016638 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
16639
16640 if (0 > ret)
16641 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053016642 else
16643 {
16644 /* Acquire wakelock to handle the case where APP's tries to suspend
16645 * immediatly after the driver gets connect request(i.e after pno)
16646 * from supplicant, this result in app's is suspending and not able
16647 * to process the connect request to AP */
16648 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
16649 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016650 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16652 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016653}
16654
16655/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016656 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016657 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016658 */
16659static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
16660{
16661 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16662 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016663 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016664 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16665 int status = 0;
16666 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
16667
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016668 /* The current firmware design does not allow PNO during any
16669 * active sessions. Hence, determine the active sessions
16670 * and return a failure.
16671 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016672 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
16673 {
16674 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016675 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016676
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016677 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
16678 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
16679 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
16680 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
16681 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053016682 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016683 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016684 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016685 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016686 }
16687 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16688 pAdapterNode = pNext;
16689 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016690 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016691}
16692
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016693void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
16694{
16695 hdd_adapter_t *pAdapter = callbackContext;
16696 hdd_context_t *pHddCtx;
16697
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016698 ENTER();
16699
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016700 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
16701 {
16702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16703 FL("Invalid adapter or adapter has invalid magic"));
16704 return;
16705 }
16706
16707 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16708 if (0 != wlan_hdd_validate_context(pHddCtx))
16709 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016710 return;
16711 }
16712
c_hpothub53c45d2014-08-18 16:53:14 +053016713 if (VOS_STATUS_SUCCESS != status)
16714 {
16715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016716 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053016717 pHddCtx->isPnoEnable = FALSE;
16718 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016719
16720 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
16721 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016722 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016723}
16724
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016725/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016726 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
16727 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016728 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016729static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016730 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16731{
16732 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016733 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016734 hdd_context_t *pHddCtx;
16735 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016736 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053016737 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
16738 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016739 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16740 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016741 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016742 hdd_config_t *pConfig = NULL;
16743 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016744
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016745 ENTER();
16746
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016747 if (NULL == pAdapter)
16748 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016750 "%s: HDD adapter is Null", __func__);
16751 return -ENODEV;
16752 }
16753
16754 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016755 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016756
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016757 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016758 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016759 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016760 }
16761
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016762 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016763 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16764 if (NULL == hHal)
16765 {
16766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16767 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016768 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016769 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016770 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16771 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
16772 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053016773 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016774 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053016775 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016776 {
16777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16778 "%s: aborting the existing scan is unsuccessfull", __func__);
16779 return -EBUSY;
16780 }
16781
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016782 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016783 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016785 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016786 return -EBUSY;
16787 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016788
c_hpothu37f21312014-04-09 21:49:54 +053016789 if (TRUE == pHddCtx->isPnoEnable)
16790 {
16791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16792 FL("already PNO is enabled"));
16793 return -EBUSY;
16794 }
c_hpothu225aa7c2014-10-22 17:45:13 +053016795
16796 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
16797 {
16798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16799 "%s: abort ROC failed ", __func__);
16800 return -EBUSY;
16801 }
16802
c_hpothu37f21312014-04-09 21:49:54 +053016803 pHddCtx->isPnoEnable = TRUE;
16804
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016805 pnoRequest.enable = 1; /*Enable PNO */
16806 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016807
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016808 if (( !pnoRequest.ucNetworksCount ) ||
16809 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016810 {
16811 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016812 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016813 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016814 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016815 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016816 goto error;
16817 }
16818
16819 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
16820 {
16821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016822 "%s: Incorrect number of channels %d",
16823 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016824 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016825 goto error;
16826 }
16827
16828 /* Framework provides one set of channels(all)
16829 * common for all saved profile */
16830 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16831 channels_allowed, &num_channels_allowed))
16832 {
16833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16834 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016835 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016836 goto error;
16837 }
16838 /* Checking each channel against allowed channel list */
16839 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053016840 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016841 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016842 char chList [(request->n_channels*5)+1];
16843 int len;
16844 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016845 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016846 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016847 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016848 if (request->channels[i]->hw_value == channels_allowed[indx])
16849 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016850 if ((!pConfig->enableDFSPnoChnlScan) &&
16851 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
16852 {
16853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16854 "%s : Dropping DFS channel : %d",
16855 __func__,channels_allowed[indx]);
16856 num_ignore_dfs_ch++;
16857 break;
16858 }
16859
Nirav Shah80830bf2013-12-31 16:35:12 +053016860 valid_ch[num_ch++] = request->channels[i]->hw_value;
16861 len += snprintf(chList+len, 5, "%d ",
16862 request->channels[i]->hw_value);
16863 break ;
16864 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016865 }
16866 }
Nirav Shah80830bf2013-12-31 16:35:12 +053016867 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016868
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016869 /*If all channels are DFS and dropped, then ignore the PNO request*/
16870 if (num_ignore_dfs_ch == request->n_channels)
16871 {
16872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16873 "%s : All requested channels are DFS channels", __func__);
16874 ret = -EINVAL;
16875 goto error;
16876 }
16877 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016878
16879 pnoRequest.aNetworks =
16880 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16881 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016882 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016883 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16884 FL("failed to allocate memory aNetworks %u"),
16885 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16886 goto error;
16887 }
16888 vos_mem_zero(pnoRequest.aNetworks,
16889 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16890
16891 /* Filling per profile params */
16892 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
16893 {
16894 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016895 request->match_sets[i].ssid.ssid_len;
16896
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016897 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
16898 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016899 {
16900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016901 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016902 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016903 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016904 goto error;
16905 }
16906
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016907 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016908 request->match_sets[i].ssid.ssid,
16909 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16911 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016912 i, pnoRequest.aNetworks[i].ssId.ssId);
16913 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
16914 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
16915 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016916
16917 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016918 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
16919 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016920
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016921 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016922 }
16923
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016924 for (i = 0; i < request->n_ssids; i++)
16925 {
16926 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016927 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016928 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016929 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016930 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016931 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016932 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016933 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016934 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016935 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016936 break;
16937 }
16938 j++;
16939 }
16940 }
16941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16942 "Number of hidden networks being Configured = %d",
16943 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080016945 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016946
16947 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
16948 if (pnoRequest.p24GProbeTemplate == NULL)
16949 {
16950 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16951 FL("failed to allocate memory p24GProbeTemplate %u"),
16952 SIR_PNO_MAX_PB_REQ_SIZE);
16953 goto error;
16954 }
16955
16956 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
16957 if (pnoRequest.p5GProbeTemplate == NULL)
16958 {
16959 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16960 FL("failed to allocate memory p5GProbeTemplate %u"),
16961 SIR_PNO_MAX_PB_REQ_SIZE);
16962 goto error;
16963 }
16964
16965 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
16966 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
16967
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053016968 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
16969 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016970 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016971 pnoRequest.us24GProbeTemplateLen = request->ie_len;
16972 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
16973 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016974
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016975 pnoRequest.us5GProbeTemplateLen = request->ie_len;
16976 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
16977 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016978 }
16979
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016980 /* Driver gets only one time interval which is hardcoded in
16981 * supplicant for 10000ms. Taking power consumption into account 6 timers
16982 * will be used, Timervalue is increased exponentially i.e 10,20,40,
16983 * 80,160,320 secs. And number of scan cycle for each timer
16984 * is configurable through INI param gPNOScanTimerRepeatValue.
16985 * If it is set to 0 only one timer will be used and PNO scan cycle
16986 * will be repeated after each interval specified by supplicant
16987 * till PNO is disabled.
16988 */
16989 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016990 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016991 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016992 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016993 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
16994
16995 tempInterval = (request->interval)/1000;
16996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16997 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
16998 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016999 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017000 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017001 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017002 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017003 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017004 tempInterval *= 2;
17005 }
17006 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017007 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017008
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017009 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017010
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017011 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017012 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17013 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017014 pAdapter->pno_req_status = 0;
17015
Nirav Shah80830bf2013-12-31 16:35:12 +053017016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17017 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017018 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
17019 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053017020
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017021 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017022 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017023 hdd_cfg80211_sched_scan_done_callback, pAdapter);
17024 if (eHAL_STATUS_SUCCESS != status)
17025 {
17026 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017027 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017028 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017029 goto error;
17030 }
17031
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017032 ret = wait_for_completion_timeout(
17033 &pAdapter->pno_comp_var,
17034 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17035 if (0 >= ret)
17036 {
17037 // Did not receive the response for PNO enable in time.
17038 // Assuming the PNO enable was success.
17039 // Returning error from here, because we timeout, results
17040 // in side effect of Wifi (Wifi Setting) not to work.
17041 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17042 FL("Timed out waiting for PNO to be Enabled"));
17043 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017044 }
17045
17046 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053017047 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017048
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017049error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17051 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053017052 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017053 if (pnoRequest.aNetworks)
17054 vos_mem_free(pnoRequest.aNetworks);
17055 if (pnoRequest.p24GProbeTemplate)
17056 vos_mem_free(pnoRequest.p24GProbeTemplate);
17057 if (pnoRequest.p5GProbeTemplate)
17058 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017059
17060 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017061 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017062}
17063
17064/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017065 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
17066 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017067 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017068static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
17069 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17070{
17071 int ret;
17072
17073 vos_ssr_protect(__func__);
17074 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
17075 vos_ssr_unprotect(__func__);
17076
17077 return ret;
17078}
17079
17080/*
17081 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
17082 * Function to disable PNO
17083 */
17084static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017085 struct net_device *dev)
17086{
17087 eHalStatus status = eHAL_STATUS_FAILURE;
17088 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17089 hdd_context_t *pHddCtx;
17090 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017091 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017092 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017093
17094 ENTER();
17095
17096 if (NULL == pAdapter)
17097 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017099 "%s: HDD adapter is Null", __func__);
17100 return -ENODEV;
17101 }
17102
17103 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017104
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017105 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017106 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017108 "%s: HDD context is Null", __func__);
17109 return -ENODEV;
17110 }
17111
17112 /* The return 0 is intentional when isLogpInProgress and
17113 * isLoadUnloadInProgress. We did observe a crash due to a return of
17114 * failure in sched_scan_stop , especially for a case where the unload
17115 * of the happens at the same time. The function __cfg80211_stop_sched_scan
17116 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
17117 * success. If it returns a failure , then its next invocation due to the
17118 * clean up of the second interface will have the dev pointer corresponding
17119 * to the first one leading to a crash.
17120 */
17121 if (pHddCtx->isLogpInProgress)
17122 {
17123 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17124 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017125 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017126 return ret;
17127 }
17128
Mihir Shete18156292014-03-11 15:38:30 +053017129 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017130 {
17131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17132 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17133 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017134 }
17135
17136 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17137 if (NULL == hHal)
17138 {
17139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17140 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017141 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017142 }
17143
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017144 pnoRequest.enable = 0; /* Disable PNO */
17145 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017146
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017147 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17148 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17149 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017150
17151 INIT_COMPLETION(pAdapter->pno_comp_var);
17152 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17153 pnoRequest.callbackContext = pAdapter;
17154 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017155 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017156 pAdapter->sessionId,
17157 NULL, pAdapter);
17158 if (eHAL_STATUS_SUCCESS != status)
17159 {
17160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17161 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017162 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017163 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017164 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017165 ret = wait_for_completion_timeout(
17166 &pAdapter->pno_comp_var,
17167 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17168 if (0 >= ret)
17169 {
17170 // Did not receive the response for PNO disable in time.
17171 // Assuming the PNO disable was success.
17172 // Returning error from here, because we timeout, results
17173 // in side effect of Wifi (Wifi Setting) not to work.
17174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17175 FL("Timed out waiting for PNO to be disabled"));
17176 ret = 0;
17177 }
17178
17179 ret = pAdapter->pno_req_status;
17180 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017181
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017182error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017184 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017185
17186 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017187 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017188}
17189
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017190/*
17191 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17192 * NL interface to disable PNO
17193 */
17194static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17195 struct net_device *dev)
17196{
17197 int ret;
17198
17199 vos_ssr_protect(__func__);
17200 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17201 vos_ssr_unprotect(__func__);
17202
17203 return ret;
17204}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017205#endif /*FEATURE_WLAN_SCAN_PNO*/
17206
17207
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017208#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017209#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017210static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17211 struct net_device *dev,
17212 u8 *peer, u8 action_code,
17213 u8 dialog_token,
17214 u16 status_code, u32 peer_capability,
17215 const u8 *buf, size_t len)
17216#else /* TDLS_MGMT_VERSION2 */
17217#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17218static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17219 struct net_device *dev,
17220 const u8 *peer, u8 action_code,
17221 u8 dialog_token, u16 status_code,
17222 u32 peer_capability, bool initiator,
17223 const u8 *buf, size_t len)
17224#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17225static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17226 struct net_device *dev,
17227 const u8 *peer, u8 action_code,
17228 u8 dialog_token, u16 status_code,
17229 u32 peer_capability, const u8 *buf,
17230 size_t len)
17231#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17232static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17233 struct net_device *dev,
17234 u8 *peer, u8 action_code,
17235 u8 dialog_token,
17236 u16 status_code, u32 peer_capability,
17237 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017238#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017239static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17240 struct net_device *dev,
17241 u8 *peer, u8 action_code,
17242 u8 dialog_token,
17243 u16 status_code, const u8 *buf,
17244 size_t len)
17245#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017246#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017247{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017248 hdd_adapter_t *pAdapter;
17249 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017250 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017251 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017252 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017253 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017254 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017255 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017256#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017257 u32 peer_capability = 0;
17258#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017259 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017260 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017261
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017262 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17263 if (NULL == pAdapter)
17264 {
17265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17266 "%s: Adapter is NULL",__func__);
17267 return -EINVAL;
17268 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017269 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17270 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17271 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017272
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017273 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017274 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017275 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017277 "Invalid arguments");
17278 return -EINVAL;
17279 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017280
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017281 if (pHddCtx->isLogpInProgress)
17282 {
17283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17284 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017285 wlan_hdd_tdls_set_link_status(pAdapter,
17286 peer,
17287 eTDLS_LINK_IDLE,
17288 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017289 return -EBUSY;
17290 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017291
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017292 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17293 {
17294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17295 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17296 return -EAGAIN;
17297 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017298
Hoonki Lee27511902013-03-14 18:19:06 -070017299 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017300 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017302 "%s: TDLS mode is disabled OR not enabled in FW."
17303 MAC_ADDRESS_STR " action %d declined.",
17304 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017305 return -ENOTSUPP;
17306 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017307
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017308 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17309
17310 if( NULL == pHddStaCtx )
17311 {
17312 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17313 "%s: HDD station context NULL ",__func__);
17314 return -EINVAL;
17315 }
17316
17317 /* STA should be connected and authenticated
17318 * before sending any TDLS frames
17319 */
17320 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17321 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17322 {
17323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17324 "STA is not connected or unauthenticated. "
17325 "connState %u, uIsAuthenticated %u",
17326 pHddStaCtx->conn_info.connState,
17327 pHddStaCtx->conn_info.uIsAuthenticated);
17328 return -EAGAIN;
17329 }
17330
Hoonki Lee27511902013-03-14 18:19:06 -070017331 /* other than teardown frame, other mgmt frames are not sent if disabled */
17332 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17333 {
17334 /* if tdls_mode is disabled to respond to peer's request */
17335 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17336 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017338 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017339 " TDLS mode is disabled. action %d declined.",
17340 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017341
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017342 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017343 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017344
17345 if (vos_max_concurrent_connections_reached())
17346 {
17347 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17348 return -EINVAL;
17349 }
Hoonki Lee27511902013-03-14 18:19:06 -070017350 }
17351
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017352 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17353 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017354 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017355 {
17356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017357 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017358 " TDLS setup is ongoing. action %d declined.",
17359 __func__, MAC_ADDR_ARRAY(peer), action_code);
17360 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017361 }
17362 }
17363
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017364 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17365 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017366 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017367 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17368 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017369 {
17370 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17371 we return error code at 'add_station()'. Hence we have this
17372 check again in addtion to add_station().
17373 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017374 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017375 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17377 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017378 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
17379 __func__, MAC_ADDR_ARRAY(peer), action_code,
17380 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053017381 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080017382 }
17383 else
17384 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017385 /* maximum reached. tweak to send error code to peer and return
17386 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017387 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17389 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017390 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
17391 __func__, MAC_ADDR_ARRAY(peer), status_code,
17392 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070017393 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017394 /* fall through to send setup resp with failure status
17395 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017396 }
17397 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017398 else
17399 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017400 mutex_lock(&pHddCtx->tdls_lock);
17401 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017402 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017403 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017404 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017406 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17407 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017408 return -EPERM;
17409 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017410 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017411 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017412 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017413
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017415 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017416 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17417 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017418
Hoonki Leea34dd892013-02-05 22:56:02 -080017419 /*Except teardown responder will not be used so just make 0*/
17420 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017421 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017422 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017423
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017424 mutex_lock(&pHddCtx->tdls_lock);
17425 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017426
17427 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17428 responder = pTdlsPeer->is_responder;
17429 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017430 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017431 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017432 "%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 -070017433 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17434 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017435 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017436 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017437 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017438 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017439 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017440
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017441 /* Discard TDLS setup if peer is removed by user app */
17442 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
17443 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17444 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
17445 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
17446
17447 mutex_lock(&pHddCtx->tdls_lock);
17448 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17449 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
17450 mutex_unlock(&pHddCtx->tdls_lock);
17451 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
17452 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
17453 MAC_ADDR_ARRAY(peer), action_code);
17454 return -EINVAL;
17455 }
17456 mutex_unlock(&pHddCtx->tdls_lock);
17457 }
17458
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017459 /* For explicit trigger of DIS_REQ come out of BMPS for
17460 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017461 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017462 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17463 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070017464 {
17465 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
17466 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017468 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017469 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
17470 if (status != VOS_STATUS_SUCCESS) {
17471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
17472 }
Hoonki Lee14621352013-04-16 17:51:19 -070017473 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017474 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017475 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017476 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
17477 }
17478 }
Hoonki Lee14621352013-04-16 17:51:19 -070017479 }
17480
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017481 /* make sure doesn't call send_mgmt() while it is pending */
17482 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
17483 {
17484 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017485 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017486 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017487 ret = -EBUSY;
17488 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017489 }
17490
17491 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017492 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
17493
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017494 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
17495 pAdapter->sessionId, peer, action_code, dialog_token,
17496 status_code, peer_capability, (tANI_U8 *)buf, len,
17497 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017498
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017499 if (VOS_STATUS_SUCCESS != status)
17500 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17502 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017503 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017504 ret = -EINVAL;
17505 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017506 }
17507
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017508 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
17509 (SIR_MAC_TDLS_DIS_RSP == action_code))
17510 {
17511 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
17512 * So we no need to wait for tdls_mgmt_comp for sending ack status.
17513 */
17514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17515 "%s: tx done for frm %u", __func__, action_code);
17516 return 0;
17517 }
17518
17519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17520 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
17521 WAIT_TIME_TDLS_MGMT);
17522
Hoonki Leed37cbb32013-04-20 00:31:14 -070017523 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
17524 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
17525
17526 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017527 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070017528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070017529 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070017530 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017531 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080017532
17533 if (pHddCtx->isLogpInProgress)
17534 {
17535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17536 "%s: LOGP in Progress. Ignore!!!", __func__);
17537 return -EAGAIN;
17538 }
Abhishek Singh837adf22015-10-01 17:37:37 +053017539 if (rc <= 0)
17540 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
17541 WLAN_LOG_INDICATOR_HOST_DRIVER,
17542 WLAN_LOG_REASON_HDD_TIME_OUT,
17543 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080017544
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017545 ret = -EINVAL;
17546 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017547 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017548 else
17549 {
17550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17551 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
17552 __func__, rc, pAdapter->mgmtTxCompletionStatus);
17553 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017554
Gopichand Nakkala05922802013-03-14 12:23:19 -070017555 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070017556 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017557 ret = max_sta_failed;
17558 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070017559 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017560
Hoonki Leea34dd892013-02-05 22:56:02 -080017561 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
17562 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017563 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17565 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017566 }
17567 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
17568 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017569 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017570 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17571 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017572 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017573
17574 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017575
17576tx_failed:
17577 /* add_station will be called before sending TDLS_SETUP_REQ and
17578 * TDLS_SETUP_RSP and as part of add_station driver will enable
17579 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
17580 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
17581 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
17582 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
17583 */
17584
17585 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17586 (SIR_MAC_TDLS_SETUP_RSP == action_code))
17587 wlan_hdd_tdls_check_bmps(pAdapter);
17588 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017589}
17590
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017591#if TDLS_MGMT_VERSION2
17592static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17593 u8 *peer, u8 action_code, u8 dialog_token,
17594 u16 status_code, u32 peer_capability,
17595 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017596#else /* TDLS_MGMT_VERSION2 */
17597#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17598static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17599 struct net_device *dev,
17600 const u8 *peer, u8 action_code,
17601 u8 dialog_token, u16 status_code,
17602 u32 peer_capability, bool initiator,
17603 const u8 *buf, size_t len)
17604#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17605static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17606 struct net_device *dev,
17607 const u8 *peer, u8 action_code,
17608 u8 dialog_token, u16 status_code,
17609 u32 peer_capability, const u8 *buf,
17610 size_t len)
17611#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17612static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17613 struct net_device *dev,
17614 u8 *peer, u8 action_code,
17615 u8 dialog_token,
17616 u16 status_code, u32 peer_capability,
17617 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017618#else
17619static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17620 u8 *peer, u8 action_code, u8 dialog_token,
17621 u16 status_code, const u8 *buf, size_t len)
17622#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017623#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017624{
17625 int ret;
17626
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017627 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017628#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017629 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17630 dialog_token, status_code,
17631 peer_capability, buf, len);
17632#else /* TDLS_MGMT_VERSION2 */
17633#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17634 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17635 dialog_token, status_code,
17636 peer_capability, initiator,
17637 buf, len);
17638#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17639 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17640 dialog_token, status_code,
17641 peer_capability, buf, len);
17642#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17643 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17644 dialog_token, status_code,
17645 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017646#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017647 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17648 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017649#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017650#endif
17651 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017652
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017653 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017654}
Atul Mittal115287b2014-07-08 13:26:33 +053017655
17656int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017657#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17658 const u8 *peer,
17659#else
Atul Mittal115287b2014-07-08 13:26:33 +053017660 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017661#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017662 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053017663 cfg80211_exttdls_callback callback)
17664{
17665
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017666 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053017667 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017668 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053017669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17670 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
17671 __func__, MAC_ADDR_ARRAY(peer));
17672
17673 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17674 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17675
17676 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017677 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17678 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17679 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017680 return -ENOTSUPP;
17681 }
17682
17683 /* To cater the requirement of establishing the TDLS link
17684 * irrespective of the data traffic , get an entry of TDLS peer.
17685 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017686 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017687 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
17688 if (pTdlsPeer == NULL) {
17689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17690 "%s: peer " MAC_ADDRESS_STR " not existing",
17691 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017692 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017693 return -EINVAL;
17694 }
17695
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017696 /* check FW TDLS Off Channel capability */
17697 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017698 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017699 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017700 {
17701 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
17702 pTdlsPeer->peerParams.global_operating_class =
17703 tdls_peer_params->global_operating_class;
17704 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
17705 pTdlsPeer->peerParams.min_bandwidth_kbps =
17706 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017707 /* check configured channel is valid, non dfs and
17708 * not current operating channel */
17709 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
17710 tdls_peer_params->channel)) &&
17711 (pHddStaCtx) &&
17712 (tdls_peer_params->channel !=
17713 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017714 {
17715 pTdlsPeer->isOffChannelConfigured = TRUE;
17716 }
17717 else
17718 {
17719 pTdlsPeer->isOffChannelConfigured = FALSE;
17720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17721 "%s: Configured Tdls Off Channel is not valid", __func__);
17722
17723 }
17724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017725 "%s: tdls_off_channel %d isOffChannelConfigured %d "
17726 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017727 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017728 pTdlsPeer->isOffChannelConfigured,
17729 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017730 }
17731 else
17732 {
17733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017734 "%s: TDLS off channel FW capability %d, "
17735 "host capab %d or Invalid TDLS Peer Params", __func__,
17736 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
17737 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017738 }
17739
Atul Mittal115287b2014-07-08 13:26:33 +053017740 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
17741
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017742 mutex_unlock(&pHddCtx->tdls_lock);
17743
Atul Mittal115287b2014-07-08 13:26:33 +053017744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17745 " %s TDLS Add Force Peer Failed",
17746 __func__);
17747 return -EINVAL;
17748 }
17749 /*EXT TDLS*/
17750
17751 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017752 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17754 " %s TDLS set callback Failed",
17755 __func__);
17756 return -EINVAL;
17757 }
17758
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017759 mutex_unlock(&pHddCtx->tdls_lock);
17760
Atul Mittal115287b2014-07-08 13:26:33 +053017761 return(0);
17762
17763}
17764
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017765int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
17766#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17767 const u8 *peer
17768#else
17769 u8 *peer
17770#endif
17771)
Atul Mittal115287b2014-07-08 13:26:33 +053017772{
17773
17774 hddTdlsPeer_t *pTdlsPeer;
17775 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053017776
Atul Mittal115287b2014-07-08 13:26:33 +053017777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17778 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
17779 __func__, MAC_ADDR_ARRAY(peer));
17780
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017781 if (0 != wlan_hdd_validate_context(pHddCtx)) {
17782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
17783 return -EINVAL;
17784 }
17785
Atul Mittal115287b2014-07-08 13:26:33 +053017786 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17787 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17788
17789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017790 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17791 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17792 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017793 return -ENOTSUPP;
17794 }
17795
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017796 mutex_lock(&pHddCtx->tdls_lock);
17797 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053017798
17799 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017800 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017801 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017802 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053017803 __func__, MAC_ADDR_ARRAY(peer));
17804 return -EINVAL;
17805 }
17806 else {
17807 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
17808 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053017809 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
17810 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017811 /* if channel switch is configured, reset
17812 the channel for this peer */
17813 if (TRUE == pTdlsPeer->isOffChannelConfigured)
17814 {
17815 pTdlsPeer->peerParams.channel = 0;
17816 pTdlsPeer->isOffChannelConfigured = FALSE;
17817 }
Atul Mittal115287b2014-07-08 13:26:33 +053017818 }
17819
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017820 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017821 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017822 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053017823 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017824 }
Atul Mittal115287b2014-07-08 13:26:33 +053017825
17826 /*EXT TDLS*/
17827
17828 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017829 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017830 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17831 " %s TDLS set callback Failed",
17832 __func__);
17833 return -EINVAL;
17834 }
Atul Mittal115287b2014-07-08 13:26:33 +053017835
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017836 mutex_unlock(&pHddCtx->tdls_lock);
17837
17838 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053017839}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017840static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017841#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17842 const u8 *peer,
17843#else
17844 u8 *peer,
17845#endif
17846 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017847{
17848 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17849 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017850 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017851 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017852
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017853 ENTER();
17854
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017855 if (!pAdapter) {
17856 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17857 return -EINVAL;
17858 }
17859
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017860 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17861 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
17862 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017863 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017864 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070017866 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017867 return -EINVAL;
17868 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017869
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017870 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017871 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017872 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017873 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017874 }
17875
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017876
17877 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017878 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017879 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017881 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
17882 "Cannot process TDLS commands",
17883 pHddCtx->cfg_ini->fEnableTDLSSupport,
17884 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017885 return -ENOTSUPP;
17886 }
17887
17888 switch (oper) {
17889 case NL80211_TDLS_ENABLE_LINK:
17890 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017891 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017892 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053017893 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
17894 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053017895 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017896 tANI_U16 numCurrTdlsPeers = 0;
17897 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017898 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053017899 tSirMacAddr peerMac;
17900 int channel;
17901 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017902
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17904 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
17905 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017906
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053017907 mutex_lock(&pHddCtx->tdls_lock);
17908 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053017909 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053017910 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053017911 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053017912 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
17913 " (oper %d) not exsting. ignored",
17914 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
17915 return -EINVAL;
17916 }
17917
17918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17919 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
17920 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
17921 "NL80211_TDLS_ENABLE_LINK");
17922
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070017923 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
17924 {
17925 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
17926 MAC_ADDRESS_STR " failed",
17927 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053017928 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070017929 return -EINVAL;
17930 }
17931
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053017932 /* before starting tdls connection, set tdls
17933 * off channel established status to default value */
17934 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053017935
17936 mutex_unlock(&pHddCtx->tdls_lock);
17937
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017938 /* TDLS Off Channel, Disable tdls channel switch,
17939 when there are more than one tdls link */
17940 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053017941 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017942 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053017943 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017944 /* get connected peer and send disable tdls off chan */
17945 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017946 if ((connPeer) &&
17947 (connPeer->isOffChannelSupported == TRUE) &&
17948 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017949 {
17950 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17951 "%s: More then one peer connected, Disable "
17952 "TDLS channel switch", __func__);
17953
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017954 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053017955 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
17956 channel = connPeer->peerParams.channel;
17957
17958 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017959
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017960 ret = sme_SendTdlsChanSwitchReq(
17961 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017962 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053017963 peerMac,
17964 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017965 TDLS_OFF_CHANNEL_BW_OFFSET,
17966 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017967 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017968 hddLog(VOS_TRACE_LEVEL_ERROR,
17969 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017970 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017971 }
17972 else
17973 {
17974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17975 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017976 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017977 "isOffChannelConfigured %d",
17978 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017979 (connPeer ? (connPeer->isOffChannelSupported)
17980 : -1),
17981 (connPeer ? (connPeer->isOffChannelConfigured)
17982 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053017983 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017984 }
17985 }
17986
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053017987 mutex_lock(&pHddCtx->tdls_lock);
17988 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17989 if ( NULL == pTdlsPeer ) {
17990 mutex_unlock(&pHddCtx->tdls_lock);
17991 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17992 "%s: " MAC_ADDRESS_STR
17993 " (oper %d) peer got freed in other context. ignored",
17994 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
17995 return -EINVAL;
17996 }
17997 peer_status = pTdlsPeer->link_status;
17998 mutex_unlock(&pHddCtx->tdls_lock);
17999
18000 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018001 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018002 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053018003
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018004 if (0 != wlan_hdd_tdls_get_link_establish_params(
18005 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018006 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018007 return -EINVAL;
18008 }
18009 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018010
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018011 ret = sme_SendTdlsLinkEstablishParams(
18012 WLAN_HDD_GET_HAL_CTX(pAdapter),
18013 pAdapter->sessionId, peer,
18014 &tdlsLinkEstablishParams);
18015 if (ret != VOS_STATUS_SUCCESS) {
18016 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
18017 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018018 /* Send TDLS peer UAPSD capabilities to the firmware and
18019 * register with the TL on after the response for this operation
18020 * is received .
18021 */
18022 ret = wait_for_completion_interruptible_timeout(
18023 &pAdapter->tdls_link_establish_req_comp,
18024 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053018025
18026 mutex_lock(&pHddCtx->tdls_lock);
18027 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18028 if ( NULL == pTdlsPeer ) {
18029 mutex_unlock(&pHddCtx->tdls_lock);
18030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18031 "%s %d: " MAC_ADDRESS_STR
18032 " (oper %d) peer got freed in other context. ignored",
18033 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
18034 (int)oper);
18035 return -EINVAL;
18036 }
18037 peer_status = pTdlsPeer->link_status;
18038 mutex_unlock(&pHddCtx->tdls_lock);
18039
18040 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018041 {
18042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018043 FL("Link Establish Request Failed Status %ld"),
18044 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018045 return -EINVAL;
18046 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018047 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018048
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018049 mutex_lock(&pHddCtx->tdls_lock);
18050 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18051 if ( NULL == pTdlsPeer ) {
18052 mutex_unlock(&pHddCtx->tdls_lock);
18053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18054 "%s: " MAC_ADDRESS_STR
18055 " (oper %d) peer got freed in other context. ignored",
18056 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18057 return -EINVAL;
18058 }
18059
Atul Mittal115287b2014-07-08 13:26:33 +053018060 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18061 eTDLS_LINK_CONNECTED,
18062 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018063 staDesc.ucSTAId = pTdlsPeer->staId;
18064 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053018065
18066 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18067 "%s: tdlsLinkEstablishParams of peer "
18068 MAC_ADDRESS_STR "uapsdQueues: %d"
18069 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
18070 "isResponder: %d peerstaId: %d",
18071 __func__,
18072 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
18073 tdlsLinkEstablishParams.uapsdQueues,
18074 tdlsLinkEstablishParams.qos,
18075 tdlsLinkEstablishParams.maxSp,
18076 tdlsLinkEstablishParams.isBufSta,
18077 tdlsLinkEstablishParams.isOffChannelSupported,
18078 tdlsLinkEstablishParams.isResponder,
18079 pTdlsPeer->staId);
18080
18081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18082 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
18083 __func__,
18084 staDesc.ucSTAId,
18085 staDesc.ucQosEnabled);
18086
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018087 ret = WLANTL_UpdateTdlsSTAClient(
18088 pHddCtx->pvosContext,
18089 &staDesc);
18090 if (ret != VOS_STATUS_SUCCESS) {
18091 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
18092 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053018093
Gopichand Nakkala471708b2013-06-04 20:03:01 +053018094 /* Mark TDLS client Authenticated .*/
18095 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
18096 pTdlsPeer->staId,
18097 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018098 if (VOS_STATUS_SUCCESS == status)
18099 {
Hoonki Lee14621352013-04-16 17:51:19 -070018100 if (pTdlsPeer->is_responder == 0)
18101 {
18102 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018103 tdlsConnInfo_t *tdlsInfo;
18104
18105 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
18106
18107 /* Initialize initiator wait callback */
18108 vos_timer_init(
18109 &pTdlsPeer->initiatorWaitTimeoutTimer,
18110 VOS_TIMER_TYPE_SW,
18111 wlan_hdd_tdls_initiator_wait_cb,
18112 tdlsInfo);
Hoonki Lee14621352013-04-16 17:51:19 -070018113
18114 wlan_hdd_tdls_timer_restart(pAdapter,
18115 &pTdlsPeer->initiatorWaitTimeoutTimer,
18116 WAIT_TIME_TDLS_INITIATOR);
18117 /* suspend initiator TX until it receives direct packet from the
18118 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018119 ret = WLANTL_SuspendDataTx(
18120 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18121 &staId, NULL);
18122 if (ret != VOS_STATUS_SUCCESS) {
18123 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
18124 }
Hoonki Lee14621352013-04-16 17:51:19 -070018125 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018126
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018127 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018128 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018129 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018130 suppChannelLen =
18131 tdlsLinkEstablishParams.supportedChannelsLen;
18132
18133 if ((suppChannelLen > 0) &&
18134 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
18135 {
18136 tANI_U8 suppPeerChannel = 0;
18137 int i = 0;
18138 for (i = 0U; i < suppChannelLen; i++)
18139 {
18140 suppPeerChannel =
18141 tdlsLinkEstablishParams.supportedChannels[i];
18142
18143 pTdlsPeer->isOffChannelSupported = FALSE;
18144 if (suppPeerChannel ==
18145 pTdlsPeer->peerParams.channel)
18146 {
18147 pTdlsPeer->isOffChannelSupported = TRUE;
18148 break;
18149 }
18150 }
18151 }
18152 else
18153 {
18154 pTdlsPeer->isOffChannelSupported = FALSE;
18155 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018156 }
18157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18158 "%s: TDLS channel switch request for channel "
18159 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018160 "%d isOffChannelSupported %d", __func__,
18161 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018162 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018163 suppChannelLen,
18164 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018165
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018166 /* TDLS Off Channel, Enable tdls channel switch,
18167 when their is only one tdls link and it supports */
18168 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18169 if ((numCurrTdlsPeers == 1) &&
18170 (TRUE == pTdlsPeer->isOffChannelSupported) &&
18171 (TRUE == pTdlsPeer->isOffChannelConfigured))
18172 {
18173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18174 "%s: Send TDLS channel switch request for channel %d",
18175 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018176
18177 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018178 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
18179 channel = pTdlsPeer->peerParams.channel;
18180
18181 mutex_unlock(&pHddCtx->tdls_lock);
18182
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018183 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
18184 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018185 peerMac,
18186 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018187 TDLS_OFF_CHANNEL_BW_OFFSET,
18188 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018189 if (ret != VOS_STATUS_SUCCESS) {
18190 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
18191 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018192 }
18193 else
18194 {
18195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18196 "%s: TDLS channel switch request not sent"
18197 " numCurrTdlsPeers %d "
18198 "isOffChannelSupported %d "
18199 "isOffChannelConfigured %d",
18200 __func__, numCurrTdlsPeers,
18201 pTdlsPeer->isOffChannelSupported,
18202 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018203 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018204 }
18205
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018206 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018207 else
18208 mutex_unlock(&pHddCtx->tdls_lock);
18209
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018210 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018211
18212 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018213 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18214 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018215 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018216 int ac;
18217 uint8 ucAc[4] = { WLANTL_AC_VO,
18218 WLANTL_AC_VI,
18219 WLANTL_AC_BK,
18220 WLANTL_AC_BE };
18221 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18222 for(ac=0; ac < 4; ac++)
18223 {
18224 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18225 pTdlsPeer->staId, ucAc[ac],
18226 tlTid[ac], tlTid[ac], 0, 0,
18227 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018228 if (status != VOS_STATUS_SUCCESS) {
18229 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18230 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018231 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018232 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018233 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018234
Bhargav Shah66896792015-10-01 18:17:37 +053018235 /* stop TCP delack timer if TDLS is enable */
18236 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18237 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053018238 hdd_wlan_tdls_enable_link_event(peer,
18239 pTdlsPeer->isOffChannelSupported,
18240 pTdlsPeer->isOffChannelConfigured,
18241 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018242 }
18243 break;
18244 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018245 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018246 tANI_U16 numCurrTdlsPeers = 0;
18247 hddTdlsPeer_t *connPeer = NULL;
18248
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18250 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18251 __func__, MAC_ADDR_ARRAY(peer));
18252
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018253 mutex_lock(&pHddCtx->tdls_lock);
18254 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018255
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018256
Sunil Dutt41de4e22013-11-14 18:09:02 +053018257 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018258 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018259 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18260 " (oper %d) not exsting. ignored",
18261 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18262 return -EINVAL;
18263 }
18264
18265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18266 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18267 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18268 "NL80211_TDLS_DISABLE_LINK");
18269
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018270 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018271 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018272 long status;
18273
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018274 /* set tdls off channel status to false for this peer */
18275 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018276 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18277 eTDLS_LINK_TEARING,
18278 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18279 eTDLS_LINK_UNSPECIFIED:
18280 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018281 mutex_unlock(&pHddCtx->tdls_lock);
18282
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018283 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18284
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018285 status = sme_DeleteTdlsPeerSta(
18286 WLAN_HDD_GET_HAL_CTX(pAdapter),
18287 pAdapter->sessionId, peer );
18288 if (status != VOS_STATUS_SUCCESS) {
18289 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18290 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018291
18292 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18293 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018294
18295 mutex_lock(&pHddCtx->tdls_lock);
18296 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18297 if ( NULL == pTdlsPeer ) {
18298 mutex_unlock(&pHddCtx->tdls_lock);
18299 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18300 " peer was freed in other context",
18301 __func__, MAC_ADDR_ARRAY(peer));
18302 return -EINVAL;
18303 }
18304
Atul Mittal271a7652014-09-12 13:18:22 +053018305 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053018306 eTDLS_LINK_IDLE,
18307 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018308 mutex_unlock(&pHddCtx->tdls_lock);
18309
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018310 if (status <= 0)
18311 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18313 "%s: Del station failed status %ld",
18314 __func__, status);
18315 return -EPERM;
18316 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018317
18318 /* TDLS Off Channel, Enable tdls channel switch,
18319 when their is only one tdls link and it supports */
18320 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18321 if (numCurrTdlsPeers == 1)
18322 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018323 tSirMacAddr peerMac;
18324 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018325
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018326 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018327 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018328
18329 if (connPeer == NULL) {
18330 mutex_unlock(&pHddCtx->tdls_lock);
18331 hddLog(VOS_TRACE_LEVEL_ERROR,
18332 "%s connPeer is NULL", __func__);
18333 return -EINVAL;
18334 }
18335
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018336 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18337 channel = connPeer->peerParams.channel;
18338
18339 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18340 "%s: TDLS channel switch "
18341 "isOffChannelSupported %d "
18342 "isOffChannelConfigured %d "
18343 "isOffChannelEstablished %d",
18344 __func__,
18345 (connPeer ? connPeer->isOffChannelSupported : -1),
18346 (connPeer ? connPeer->isOffChannelConfigured : -1),
18347 (connPeer ? connPeer->isOffChannelEstablished : -1));
18348
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018349 if ((connPeer) &&
18350 (connPeer->isOffChannelSupported == TRUE) &&
18351 (connPeer->isOffChannelConfigured == TRUE))
18352 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018353 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018354 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018355 status = sme_SendTdlsChanSwitchReq(
18356 WLAN_HDD_GET_HAL_CTX(pAdapter),
18357 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018358 peerMac,
18359 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018360 TDLS_OFF_CHANNEL_BW_OFFSET,
18361 TDLS_CHANNEL_SWITCH_ENABLE);
18362 if (status != VOS_STATUS_SUCCESS) {
18363 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18364 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018365 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018366 else
18367 mutex_unlock(&pHddCtx->tdls_lock);
18368 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018369 else
18370 {
18371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18372 "%s: TDLS channel switch request not sent "
18373 "numCurrTdlsPeers %d ",
18374 __func__, numCurrTdlsPeers);
18375 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018376 }
18377 else
18378 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018379 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18381 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080018382 }
Bhargav Shah66896792015-10-01 18:17:37 +053018383 if (numCurrTdlsPeers == 0) {
18384 /* start TCP delack timer if TDLS is disable */
18385 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18386 hdd_manage_delack_timer(pHddCtx);
18387 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018388 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018389 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018390 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018391 {
Atul Mittal115287b2014-07-08 13:26:33 +053018392 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018393
Atul Mittal115287b2014-07-08 13:26:33 +053018394 if (0 != status)
18395 {
18396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018397 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053018398 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018399 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053018400 break;
18401 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018402 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018403 {
Atul Mittal115287b2014-07-08 13:26:33 +053018404 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
18405 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018406 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053018407 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018408
Atul Mittal115287b2014-07-08 13:26:33 +053018409 if (0 != status)
18410 {
18411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018412 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053018413 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053018414 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053018415 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018416 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018417 case NL80211_TDLS_DISCOVERY_REQ:
18418 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018420 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018421 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018422 return -ENOTSUPP;
18423 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18425 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018426 return -ENOTSUPP;
18427 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018428
18429 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018430 return 0;
18431}
Chilam NG571c65a2013-01-19 12:27:36 +053018432
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018433static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018434#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18435 const u8 *peer,
18436#else
18437 u8 *peer,
18438#endif
18439 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018440{
18441 int ret;
18442
18443 vos_ssr_protect(__func__);
18444 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
18445 vos_ssr_unprotect(__func__);
18446
18447 return ret;
18448}
18449
Chilam NG571c65a2013-01-19 12:27:36 +053018450int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
18451 struct net_device *dev, u8 *peer)
18452{
Arif Hussaina7c8e412013-11-20 11:06:42 -080018453 hddLog(VOS_TRACE_LEVEL_INFO,
18454 "tdls send discover req: "MAC_ADDRESS_STR,
18455 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053018456
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018457#if TDLS_MGMT_VERSION2
18458 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18459 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18460#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018461#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18462 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18463 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
18464#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18465 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18466 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18467#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18468 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18469 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18470#else
Chilam NG571c65a2013-01-19 12:27:36 +053018471 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18472 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018473#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018474#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053018475}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018476#endif
18477
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018478#ifdef WLAN_FEATURE_GTK_OFFLOAD
18479/*
18480 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
18481 * Callback rountine called upon receiving response for
18482 * get offload info
18483 */
18484void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
18485 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
18486{
18487
18488 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018489 tANI_U8 tempReplayCounter[8];
18490 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018491
18492 ENTER();
18493
18494 if (NULL == pAdapter)
18495 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018497 "%s: HDD adapter is Null", __func__);
18498 return ;
18499 }
18500
18501 if (NULL == pGtkOffloadGetInfoRsp)
18502 {
18503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18504 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
18505 return ;
18506 }
18507
18508 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
18509 {
18510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18511 "%s: wlan Failed to get replay counter value",
18512 __func__);
18513 return ;
18514 }
18515
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018516 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18517 /* Update replay counter */
18518 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
18519 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18520
18521 {
18522 /* changing from little to big endian since supplicant
18523 * works on big endian format
18524 */
18525 int i;
18526 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18527
18528 for (i = 0; i < 8; i++)
18529 {
18530 tempReplayCounter[7-i] = (tANI_U8)p[i];
18531 }
18532 }
18533
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018534 /* Update replay counter to NL */
18535 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018536 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018537}
18538
18539/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018540 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018541 * This function is used to offload GTK rekeying job to the firmware.
18542 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018543int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018544 struct cfg80211_gtk_rekey_data *data)
18545{
18546 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18547 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18548 hdd_station_ctx_t *pHddStaCtx;
18549 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018550 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018551 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018552 eHalStatus status = eHAL_STATUS_FAILURE;
18553
18554 ENTER();
18555
18556 if (NULL == pAdapter)
18557 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018559 "%s: HDD adapter is Null", __func__);
18560 return -ENODEV;
18561 }
18562
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018563 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18564 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
18565 pAdapter->sessionId, pAdapter->device_mode));
18566
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018567 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018568 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018569 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018570 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018571 }
18572
18573 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18574 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18575 if (NULL == hHal)
18576 {
18577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18578 "%s: HAL context is Null!!!", __func__);
18579 return -EAGAIN;
18580 }
18581
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018582 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
18583 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
18584 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
18585 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018586 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018587 {
18588 /* changing from big to little endian since driver
18589 * works on little endian format
18590 */
18591 tANI_U8 *p =
18592 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
18593 int i;
18594
18595 for (i = 0; i < 8; i++)
18596 {
18597 p[7-i] = data->replay_ctr[i];
18598 }
18599 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018600
18601 if (TRUE == pHddCtx->hdd_wlan_suspended)
18602 {
18603 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018604 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
18605 sizeof (tSirGtkOffloadParams));
18606 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018607 pAdapter->sessionId);
18608
18609 if (eHAL_STATUS_SUCCESS != status)
18610 {
18611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18612 "%s: sme_SetGTKOffload failed, returned %d",
18613 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018614
18615 /* Need to clear any trace of key value in the memory.
18616 * Thus zero out the memory even though it is local
18617 * variable.
18618 */
18619 vos_mem_zero(&hddGtkOffloadReqParams,
18620 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018621 return status;
18622 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18624 "%s: sme_SetGTKOffload successfull", __func__);
18625 }
18626 else
18627 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18629 "%s: wlan not suspended GTKOffload request is stored",
18630 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018631 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018632
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018633 /* Need to clear any trace of key value in the memory.
18634 * Thus zero out the memory even though it is local
18635 * variable.
18636 */
18637 vos_mem_zero(&hddGtkOffloadReqParams,
18638 sizeof(hddGtkOffloadReqParams));
18639
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018640 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018641 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018642}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018643
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018644int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
18645 struct cfg80211_gtk_rekey_data *data)
18646{
18647 int ret;
18648
18649 vos_ssr_protect(__func__);
18650 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
18651 vos_ssr_unprotect(__func__);
18652
18653 return ret;
18654}
18655#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018656/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018657 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018658 * This function is used to set access control policy
18659 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018660static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18661 struct net_device *dev,
18662 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018663{
18664 int i;
18665 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18666 hdd_hostapd_state_t *pHostapdState;
18667 tsap_Config_t *pConfig;
18668 v_CONTEXT_t pVosContext = NULL;
18669 hdd_context_t *pHddCtx;
18670 int status;
18671
18672 ENTER();
18673
18674 if (NULL == pAdapter)
18675 {
18676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18677 "%s: HDD adapter is Null", __func__);
18678 return -ENODEV;
18679 }
18680
18681 if (NULL == params)
18682 {
18683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18684 "%s: params is Null", __func__);
18685 return -EINVAL;
18686 }
18687
18688 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18689 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018690 if (0 != status)
18691 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018692 return status;
18693 }
18694
18695 pVosContext = pHddCtx->pvosContext;
18696 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
18697
18698 if (NULL == pHostapdState)
18699 {
18700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18701 "%s: pHostapdState is Null", __func__);
18702 return -EINVAL;
18703 }
18704
18705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
18706 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018707 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18708 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
18709 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018710
18711 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
18712 {
18713 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
18714
18715 /* default value */
18716 pConfig->num_accept_mac = 0;
18717 pConfig->num_deny_mac = 0;
18718
18719 /**
18720 * access control policy
18721 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
18722 * listed in hostapd.deny file.
18723 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
18724 * listed in hostapd.accept file.
18725 */
18726 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
18727 {
18728 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
18729 }
18730 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
18731 {
18732 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
18733 }
18734 else
18735 {
18736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18737 "%s:Acl Policy : %d is not supported",
18738 __func__, params->acl_policy);
18739 return -ENOTSUPP;
18740 }
18741
18742 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
18743 {
18744 pConfig->num_accept_mac = params->n_acl_entries;
18745 for (i = 0; i < params->n_acl_entries; i++)
18746 {
18747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18748 "** Add ACL MAC entry %i in WhiletList :"
18749 MAC_ADDRESS_STR, i,
18750 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18751
18752 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
18753 sizeof(qcmacaddr));
18754 }
18755 }
18756 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
18757 {
18758 pConfig->num_deny_mac = params->n_acl_entries;
18759 for (i = 0; i < params->n_acl_entries; i++)
18760 {
18761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18762 "** Add ACL MAC entry %i in BlackList :"
18763 MAC_ADDRESS_STR, i,
18764 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18765
18766 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
18767 sizeof(qcmacaddr));
18768 }
18769 }
18770
18771 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
18772 {
18773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18774 "%s: SAP Set Mac Acl fail", __func__);
18775 return -EINVAL;
18776 }
18777 }
18778 else
18779 {
18780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053018781 "%s: Invalid device_mode = %s (%d)",
18782 __func__, hdd_device_modetoString(pAdapter->device_mode),
18783 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018784 return -EINVAL;
18785 }
18786
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018787 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018788 return 0;
18789}
18790
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018791static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18792 struct net_device *dev,
18793 const struct cfg80211_acl_data *params)
18794{
18795 int ret;
18796 vos_ssr_protect(__func__);
18797 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
18798 vos_ssr_unprotect(__func__);
18799
18800 return ret;
18801}
18802
Leo Chang9056f462013-08-01 19:21:11 -070018803#ifdef WLAN_NL80211_TESTMODE
18804#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070018805void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070018806(
18807 void *pAdapter,
18808 void *indCont
18809)
18810{
Leo Changd9df8aa2013-09-26 13:32:26 -070018811 tSirLPHBInd *lphbInd;
18812 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053018813 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070018814
18815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018816 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070018817
c_hpothu73f35e62014-04-18 13:40:08 +053018818 if (pAdapter == NULL)
18819 {
18820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18821 "%s: pAdapter is NULL\n",__func__);
18822 return;
18823 }
18824
Leo Chang9056f462013-08-01 19:21:11 -070018825 if (NULL == indCont)
18826 {
18827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018828 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070018829 return;
18830 }
18831
c_hpothu73f35e62014-04-18 13:40:08 +053018832 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070018833 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070018834 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053018835 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070018836 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070018837 GFP_ATOMIC);
18838 if (!skb)
18839 {
18840 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18841 "LPHB timeout, NL buffer alloc fail");
18842 return;
18843 }
18844
Leo Changac3ba772013-10-07 09:47:04 -070018845 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070018846 {
18847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18848 "WLAN_HDD_TM_ATTR_CMD put fail");
18849 goto nla_put_failure;
18850 }
Leo Changac3ba772013-10-07 09:47:04 -070018851 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070018852 {
18853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18854 "WLAN_HDD_TM_ATTR_TYPE put fail");
18855 goto nla_put_failure;
18856 }
Leo Changac3ba772013-10-07 09:47:04 -070018857 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070018858 sizeof(tSirLPHBInd), lphbInd))
18859 {
18860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18861 "WLAN_HDD_TM_ATTR_DATA put fail");
18862 goto nla_put_failure;
18863 }
Leo Chang9056f462013-08-01 19:21:11 -070018864 cfg80211_testmode_event(skb, GFP_ATOMIC);
18865 return;
18866
18867nla_put_failure:
18868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18869 "NLA Put fail");
18870 kfree_skb(skb);
18871
18872 return;
18873}
18874#endif /* FEATURE_WLAN_LPHB */
18875
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018876static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070018877{
18878 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
18879 int err = 0;
18880#ifdef FEATURE_WLAN_LPHB
18881 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070018882 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018883
18884 ENTER();
18885
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018886 err = wlan_hdd_validate_context(pHddCtx);
18887 if (0 != err)
18888 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018889 return err;
18890 }
Leo Chang9056f462013-08-01 19:21:11 -070018891#endif /* FEATURE_WLAN_LPHB */
18892
18893 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
18894 if (err)
18895 {
18896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18897 "%s Testmode INV ATTR", __func__);
18898 return err;
18899 }
18900
18901 if (!tb[WLAN_HDD_TM_ATTR_CMD])
18902 {
18903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18904 "%s Testmode INV CMD", __func__);
18905 return -EINVAL;
18906 }
18907
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018908 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18909 TRACE_CODE_HDD_CFG80211_TESTMODE,
18910 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070018911 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
18912 {
18913#ifdef FEATURE_WLAN_LPHB
18914 /* Low Power Heartbeat configuration request */
18915 case WLAN_HDD_TM_CMD_WLAN_HB:
18916 {
18917 int buf_len;
18918 void *buf;
18919 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080018920 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070018921
18922 if (!tb[WLAN_HDD_TM_ATTR_DATA])
18923 {
18924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18925 "%s Testmode INV DATA", __func__);
18926 return -EINVAL;
18927 }
18928
18929 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
18930 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080018931
18932 hb_params_temp =(tSirLPHBReq *)buf;
18933 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
18934 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
18935 return -EINVAL;
18936
Leo Chang9056f462013-08-01 19:21:11 -070018937 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
18938 if (NULL == hb_params)
18939 {
18940 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18941 "%s Request Buffer Alloc Fail", __func__);
18942 return -EINVAL;
18943 }
18944
18945 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070018946 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
18947 hb_params,
18948 wlan_hdd_cfg80211_lphb_ind_handler);
18949 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070018950 {
Leo Changd9df8aa2013-09-26 13:32:26 -070018951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18952 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070018953 vos_mem_free(hb_params);
18954 }
Leo Chang9056f462013-08-01 19:21:11 -070018955 return 0;
18956 }
18957#endif /* FEATURE_WLAN_LPHB */
18958 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18960 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070018961 return -EOPNOTSUPP;
18962 }
18963
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018964 EXIT();
18965 return err;
Leo Chang9056f462013-08-01 19:21:11 -070018966}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018967
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053018968static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
18969#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
18970 struct wireless_dev *wdev,
18971#endif
18972 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018973{
18974 int ret;
18975
18976 vos_ssr_protect(__func__);
18977 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
18978 vos_ssr_unprotect(__func__);
18979
18980 return ret;
18981}
Leo Chang9056f462013-08-01 19:21:11 -070018982#endif /* CONFIG_NL80211_TESTMODE */
18983
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018984static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018985 struct net_device *dev,
18986 int idx, struct survey_info *survey)
18987{
18988 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18989 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053018990 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018991 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053018992 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018993 v_S7_t snr,rssi;
18994 int status, i, j, filled = 0;
18995
18996 ENTER();
18997
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018998 if (NULL == pAdapter)
18999 {
19000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19001 "%s: HDD adapter is Null", __func__);
19002 return -ENODEV;
19003 }
19004
19005 if (NULL == wiphy)
19006 {
19007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19008 "%s: wiphy is Null", __func__);
19009 return -ENODEV;
19010 }
19011
19012 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19013 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019014 if (0 != status)
19015 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019016 return status;
19017 }
19018
Mihir Sheted9072e02013-08-21 17:02:29 +053019019 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19020
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019021 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053019022 0 != pAdapter->survey_idx ||
19023 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019024 {
19025 /* The survey dump ops when implemented completely is expected to
19026 * return a survey of all channels and the ops is called by the
19027 * kernel with incremental values of the argument 'idx' till it
19028 * returns -ENONET. But we can only support the survey for the
19029 * operating channel for now. survey_idx is used to track
19030 * that the ops is called only once and then return -ENONET for
19031 * the next iteration
19032 */
19033 pAdapter->survey_idx = 0;
19034 return -ENONET;
19035 }
19036
Mukul Sharma9d5233b2015-06-11 20:28:20 +053019037 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
19038 {
19039 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19040 "%s: Roaming in progress, hence return ", __func__);
19041 return -ENONET;
19042 }
19043
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019044 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19045
19046 wlan_hdd_get_snr(pAdapter, &snr);
19047 wlan_hdd_get_rssi(pAdapter, &rssi);
19048
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019049 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19050 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
19051 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019052 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
19053 hdd_wlan_get_freq(channel, &freq);
19054
19055
19056 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
19057 {
19058 if (NULL == wiphy->bands[i])
19059 {
19060 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
19061 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
19062 continue;
19063 }
19064
19065 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
19066 {
19067 struct ieee80211_supported_band *band = wiphy->bands[i];
19068
19069 if (band->channels[j].center_freq == (v_U16_t)freq)
19070 {
19071 survey->channel = &band->channels[j];
19072 /* The Rx BDs contain SNR values in dB for the received frames
19073 * while the supplicant expects noise. So we calculate and
19074 * return the value of noise (dBm)
19075 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
19076 */
19077 survey->noise = rssi - snr;
19078 survey->filled = SURVEY_INFO_NOISE_DBM;
19079 filled = 1;
19080 }
19081 }
19082 }
19083
19084 if (filled)
19085 pAdapter->survey_idx = 1;
19086 else
19087 {
19088 pAdapter->survey_idx = 0;
19089 return -ENONET;
19090 }
19091
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019092 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019093 return 0;
19094}
19095
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019096static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
19097 struct net_device *dev,
19098 int idx, struct survey_info *survey)
19099{
19100 int ret;
19101
19102 vos_ssr_protect(__func__);
19103 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
19104 vos_ssr_unprotect(__func__);
19105
19106 return ret;
19107}
19108
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019109/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019110 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019111 * this is called when cfg80211 driver resume
19112 * driver updates latest sched_scan scan result(if any) to cfg80211 database
19113 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019114int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019115{
19116 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19117 hdd_adapter_t *pAdapter;
19118 hdd_adapter_list_node_t *pAdapterNode, *pNext;
19119 VOS_STATUS status = VOS_STATUS_SUCCESS;
19120
19121 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019122
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019123 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019124 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019125 return 0;
19126 }
19127
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019128 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
19129 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019130 spin_lock(&pHddCtx->schedScan_lock);
19131 pHddCtx->isWiphySuspended = FALSE;
19132 if (TRUE != pHddCtx->isSchedScanUpdatePending)
19133 {
19134 spin_unlock(&pHddCtx->schedScan_lock);
19135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19136 "%s: Return resume is not due to PNO indication", __func__);
19137 return 0;
19138 }
19139 // Reset flag to avoid updatating cfg80211 data old results again
19140 pHddCtx->isSchedScanUpdatePending = FALSE;
19141 spin_unlock(&pHddCtx->schedScan_lock);
19142
19143 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
19144
19145 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
19146 {
19147 pAdapter = pAdapterNode->pAdapter;
19148 if ( (NULL != pAdapter) &&
19149 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
19150 {
19151 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019152 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19154 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019155 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019156 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019157 {
19158 /* Acquire wakelock to handle the case where APP's tries to
19159 * suspend immediately after updating the scan results. Whis
19160 * results in app's is in suspended state and not able to
19161 * process the connect request to AP
19162 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053019163 hdd_prevent_suspend_timeout(2000,
19164 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019165 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019166 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019167
19168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19169 "%s : cfg80211 scan result database updated", __func__);
19170
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019171 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019172 return 0;
19173
19174 }
19175 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19176 pAdapterNode = pNext;
19177 }
19178
19179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19180 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019181 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019182 return 0;
19183}
19184
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019185int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
19186{
19187 int ret;
19188
19189 vos_ssr_protect(__func__);
19190 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
19191 vos_ssr_unprotect(__func__);
19192
19193 return ret;
19194}
19195
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019196/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019197 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019198 * this is called when cfg80211 driver suspends
19199 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019200int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019201 struct cfg80211_wowlan *wow)
19202{
19203 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019204 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019205
19206 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019207
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019208 ret = wlan_hdd_validate_context(pHddCtx);
19209 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019210 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019211 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019212 }
19213
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019214
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019215 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19216 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
19217 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019218 pHddCtx->isWiphySuspended = TRUE;
19219
19220 EXIT();
19221
19222 return 0;
19223}
19224
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019225int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19226 struct cfg80211_wowlan *wow)
19227{
19228 int ret;
19229
19230 vos_ssr_protect(__func__);
19231 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19232 vos_ssr_unprotect(__func__);
19233
19234 return ret;
19235}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019236
19237#ifdef FEATURE_OEM_DATA_SUPPORT
19238static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019239 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019240{
19241 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19242
19243 ENTER();
19244
19245 if (wlan_hdd_validate_context(pHddCtx)) {
19246 return;
19247 }
19248 if (!pMsg)
19249 {
19250 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
19251 return;
19252 }
19253
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019254 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019255
19256 EXIT();
19257 return;
19258
19259}
19260
19261void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019262 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019263{
19264 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19265
19266 ENTER();
19267
19268 if (wlan_hdd_validate_context(pHddCtx)) {
19269 return;
19270 }
19271
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019272 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019273
19274 switch(evType) {
19275 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019276 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019277 break;
19278 default:
19279 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
19280 break;
19281 }
19282 EXIT();
19283}
19284#endif
19285
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019286/**
19287 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
19288 * @wiphy: Pointer to wiphy
19289 * @wdev: Pointer to wireless device structure
19290 *
19291 * This function is used to abort an ongoing scan
19292 *
19293 * Return: None
19294 */
19295static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19296 struct wireless_dev *wdev)
19297{
19298 struct net_device *dev = wdev->netdev;
19299 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
19300 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
19301 int ret;
19302
19303 ENTER();
19304
19305 if (NULL == adapter) {
19306 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
19307 return;
19308 }
19309
19310 ret = wlan_hdd_validate_context(hdd_ctx);
19311 if (0 != ret)
19312 return;
19313
19314 wlan_hdd_scan_abort(adapter);
19315
19316 return;
19317}
19318
19319/**
19320 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
19321 * @wiphy: Pointer to wiphy
19322 * @wdev: Pointer to wireless device structure
19323 *
19324 * Return: None
19325 */
19326void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19327 struct wireless_dev *wdev)
19328{
19329 vos_ssr_protect(__func__);
19330 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
19331 vos_ssr_unprotect(__func__);
19332
19333 return;
19334}
19335
Jeff Johnson295189b2012-06-20 16:38:30 -070019336/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019337static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070019338{
19339 .add_virtual_intf = wlan_hdd_add_virtual_intf,
19340 .del_virtual_intf = wlan_hdd_del_virtual_intf,
19341 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
19342 .change_station = wlan_hdd_change_station,
19343#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
19344 .add_beacon = wlan_hdd_cfg80211_add_beacon,
19345 .del_beacon = wlan_hdd_cfg80211_del_beacon,
19346 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019347#else
19348 .start_ap = wlan_hdd_cfg80211_start_ap,
19349 .change_beacon = wlan_hdd_cfg80211_change_beacon,
19350 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070019351#endif
19352 .change_bss = wlan_hdd_cfg80211_change_bss,
19353 .add_key = wlan_hdd_cfg80211_add_key,
19354 .get_key = wlan_hdd_cfg80211_get_key,
19355 .del_key = wlan_hdd_cfg80211_del_key,
19356 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019357#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070019358 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019359#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019360 .scan = wlan_hdd_cfg80211_scan,
19361 .connect = wlan_hdd_cfg80211_connect,
19362 .disconnect = wlan_hdd_cfg80211_disconnect,
19363 .join_ibss = wlan_hdd_cfg80211_join_ibss,
19364 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
19365 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
19366 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
19367 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070019368 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
19369 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053019370 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070019371#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19372 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
19373 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
19374 .set_txq_params = wlan_hdd_set_txq_params,
19375#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019376 .get_station = wlan_hdd_cfg80211_get_station,
19377 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
19378 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019379 .add_station = wlan_hdd_cfg80211_add_station,
19380#ifdef FEATURE_WLAN_LFR
19381 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
19382 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
19383 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
19384#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019385#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
19386 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
19387#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019388#ifdef FEATURE_WLAN_TDLS
19389 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
19390 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
19391#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019392#ifdef WLAN_FEATURE_GTK_OFFLOAD
19393 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
19394#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019395#ifdef FEATURE_WLAN_SCAN_PNO
19396 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
19397 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
19398#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019399 .resume = wlan_hdd_cfg80211_resume_wlan,
19400 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019401 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070019402#ifdef WLAN_NL80211_TESTMODE
19403 .testmode_cmd = wlan_hdd_cfg80211_testmode,
19404#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019405 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019406 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Jeff Johnson295189b2012-06-20 16:38:30 -070019407};
19408