blob: 264ec177ce204f23f184e5934b430a21573f599b [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Masti, Narayanraddie1892a52015-12-15 15:01:01 +05302 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530100
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
102#define g_mode_rates_size (12)
103#define a_mode_rates_size (8)
104#define FREQ_BASE_80211G (2407)
105#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700106#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530107#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800109 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700110
111#define HDD2GHZCHAN(freq, chan, flag) { \
112 .band = IEEE80211_BAND_2GHZ, \
113 .center_freq = (freq), \
114 .hw_value = (chan),\
115 .flags = (flag), \
116 .max_antenna_gain = 0 ,\
117 .max_power = 30, \
118}
119
120#define HDD5GHZCHAN(freq, chan, flag) { \
121 .band = IEEE80211_BAND_5GHZ, \
122 .center_freq = (freq), \
123 .hw_value = (chan),\
124 .flags = (flag), \
125 .max_antenna_gain = 0 ,\
126 .max_power = 30, \
127}
128
129#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
130{\
131 .bitrate = rate, \
132 .hw_value = rate_id, \
133 .flags = flag, \
134}
135
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530136#ifdef WLAN_FEATURE_VOWIFI_11R
137#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
138#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
139#endif
140
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530141#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530142#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143
Sunil Duttc69bccb2014-05-26 21:30:20 +0530144#ifdef WLAN_FEATURE_LINK_LAYER_STATS
145/*
146 * Used to allocate the size of 4096 for the link layer stats.
147 * The size of 4096 is considered assuming that all data per
148 * respective event fit with in the limit.Please take a call
149 * on the limit based on the data requirements on link layer
150 * statistics.
151 */
152#define LL_STATS_EVENT_BUF_SIZE 4096
153#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530154#ifdef WLAN_FEATURE_EXTSCAN
155/*
156 * Used to allocate the size of 4096 for the EXTScan NL data.
157 * The size of 4096 is considered assuming that all data per
158 * respective event fit with in the limit.Please take a call
159 * on the limit based on the data requirements.
160 */
161
162#define EXTSCAN_EVENT_BUF_SIZE 4096
163#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
164#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530165
Atul Mittal115287b2014-07-08 13:26:33 +0530166/*EXT TDLS*/
167/*
168 * Used to allocate the size of 4096 for the TDLS.
169 * The size of 4096 is considered assuming that all data per
170 * respective event fit with in the limit.Please take a call
171 * on the limit based on the data requirements on link layer
172 * statistics.
173 */
174#define EXTTDLS_EVENT_BUF_SIZE 4096
175
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530176/*
177 * Values for Mac spoofing feature
178 *
179 */
180#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
181#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
182#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530183#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
184
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530185
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530186static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700187{
188 WLAN_CIPHER_SUITE_WEP40,
189 WLAN_CIPHER_SUITE_WEP104,
190 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800191#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700192#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
193 WLAN_CIPHER_SUITE_KRK,
194 WLAN_CIPHER_SUITE_CCMP,
195#else
196 WLAN_CIPHER_SUITE_CCMP,
197#endif
198#ifdef FEATURE_WLAN_WAPI
199 WLAN_CIPHER_SUITE_SMS4,
200#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700201#ifdef WLAN_FEATURE_11W
202 WLAN_CIPHER_SUITE_AES_CMAC,
203#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700204};
205
206static inline int is_broadcast_ether_addr(const u8 *addr)
207{
208 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
209 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
210}
211
Agrawal Ashish97dec502015-11-26 20:20:58 +0530212const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530213{
Jeff Johnson295189b2012-06-20 16:38:30 -0700214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2417, 2, 0) ,
216 HDD2GHZCHAN(2422, 3, 0) ,
217 HDD2GHZCHAN(2427, 4, 0) ,
218 HDD2GHZCHAN(2432, 5, 0) ,
219 HDD2GHZCHAN(2437, 6, 0) ,
220 HDD2GHZCHAN(2442, 7, 0) ,
221 HDD2GHZCHAN(2447, 8, 0) ,
222 HDD2GHZCHAN(2452, 9, 0) ,
223 HDD2GHZCHAN(2457, 10, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225 HDD2GHZCHAN(2467, 12, 0) ,
226 HDD2GHZCHAN(2472, 13, 0) ,
227 HDD2GHZCHAN(2484, 14, 0) ,
228};
229
Agrawal Ashish97dec502015-11-26 20:20:58 +0530230const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700231{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700232 HDD5GHZCHAN(4920, 240, 0) ,
233 HDD5GHZCHAN(4940, 244, 0) ,
234 HDD5GHZCHAN(4960, 248, 0) ,
235 HDD5GHZCHAN(4980, 252, 0) ,
236 HDD5GHZCHAN(5040, 208, 0) ,
237 HDD5GHZCHAN(5060, 212, 0) ,
238 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD5GHZCHAN(5180, 36, 0) ,
240 HDD5GHZCHAN(5200, 40, 0) ,
241 HDD5GHZCHAN(5220, 44, 0) ,
242 HDD5GHZCHAN(5240, 48, 0) ,
243 HDD5GHZCHAN(5260, 52, 0) ,
244 HDD5GHZCHAN(5280, 56, 0) ,
245 HDD5GHZCHAN(5300, 60, 0) ,
246 HDD5GHZCHAN(5320, 64, 0) ,
247 HDD5GHZCHAN(5500,100, 0) ,
248 HDD5GHZCHAN(5520,104, 0) ,
249 HDD5GHZCHAN(5540,108, 0) ,
250 HDD5GHZCHAN(5560,112, 0) ,
251 HDD5GHZCHAN(5580,116, 0) ,
252 HDD5GHZCHAN(5600,120, 0) ,
253 HDD5GHZCHAN(5620,124, 0) ,
254 HDD5GHZCHAN(5640,128, 0) ,
255 HDD5GHZCHAN(5660,132, 0) ,
256 HDD5GHZCHAN(5680,136, 0) ,
257 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800258#ifdef FEATURE_WLAN_CH144
259 HDD5GHZCHAN(5720,144, 0) ,
260#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 HDD5GHZCHAN(5745,149, 0) ,
262 HDD5GHZCHAN(5765,153, 0) ,
263 HDD5GHZCHAN(5785,157, 0) ,
264 HDD5GHZCHAN(5805,161, 0) ,
265 HDD5GHZCHAN(5825,165, 0) ,
266};
267
268static struct ieee80211_rate g_mode_rates[] =
269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530270 HDD_G_MODE_RATETAB(10, 0x1, 0),
271 HDD_G_MODE_RATETAB(20, 0x2, 0),
272 HDD_G_MODE_RATETAB(55, 0x4, 0),
273 HDD_G_MODE_RATETAB(110, 0x8, 0),
274 HDD_G_MODE_RATETAB(60, 0x10, 0),
275 HDD_G_MODE_RATETAB(90, 0x20, 0),
276 HDD_G_MODE_RATETAB(120, 0x40, 0),
277 HDD_G_MODE_RATETAB(180, 0x80, 0),
278 HDD_G_MODE_RATETAB(240, 0x100, 0),
279 HDD_G_MODE_RATETAB(360, 0x200, 0),
280 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282};
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
284static struct ieee80211_rate a_mode_rates[] =
285{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530286 HDD_G_MODE_RATETAB(60, 0x10, 0),
287 HDD_G_MODE_RATETAB(90, 0x20, 0),
288 HDD_G_MODE_RATETAB(120, 0x40, 0),
289 HDD_G_MODE_RATETAB(180, 0x80, 0),
290 HDD_G_MODE_RATETAB(240, 0x100, 0),
291 HDD_G_MODE_RATETAB(360, 0x200, 0),
292 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 HDD_G_MODE_RATETAB(540, 0x800, 0),
294};
295
296static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
297{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530298 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700299 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
300 .band = IEEE80211_BAND_2GHZ,
301 .bitrates = g_mode_rates,
302 .n_bitrates = g_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
308 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
309 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
310 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
311 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
312 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
313};
314
Jeff Johnson295189b2012-06-20 16:38:30 -0700315static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
316{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530317 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
319 .band = IEEE80211_BAND_5GHZ,
320 .bitrates = a_mode_rates,
321 .n_bitrates = a_mode_rates_size,
322 .ht_cap.ht_supported = 1,
323 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
324 | IEEE80211_HT_CAP_GRN_FLD
325 | IEEE80211_HT_CAP_DSSSCCK40
326 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
327 | IEEE80211_HT_CAP_SGI_40
328 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
329 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
330 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
331 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
332 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
333 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
334};
335
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530336/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 TX/RX direction for each kind of interface */
338static const struct ieee80211_txrx_stypes
339wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
340 [NL80211_IFTYPE_STATION] = {
341 .tx = 0xffff,
342 .rx = BIT(SIR_MAC_MGMT_ACTION) |
343 BIT(SIR_MAC_MGMT_PROBE_REQ),
344 },
345 [NL80211_IFTYPE_AP] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
348 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
349 BIT(SIR_MAC_MGMT_PROBE_REQ) |
350 BIT(SIR_MAC_MGMT_DISASSOC) |
351 BIT(SIR_MAC_MGMT_AUTH) |
352 BIT(SIR_MAC_MGMT_DEAUTH) |
353 BIT(SIR_MAC_MGMT_ACTION),
354 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700355 [NL80211_IFTYPE_ADHOC] = {
356 .tx = 0xffff,
357 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
358 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
359 BIT(SIR_MAC_MGMT_PROBE_REQ) |
360 BIT(SIR_MAC_MGMT_DISASSOC) |
361 BIT(SIR_MAC_MGMT_AUTH) |
362 BIT(SIR_MAC_MGMT_DEAUTH) |
363 BIT(SIR_MAC_MGMT_ACTION),
364 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 [NL80211_IFTYPE_P2P_CLIENT] = {
366 .tx = 0xffff,
367 .rx = BIT(SIR_MAC_MGMT_ACTION) |
368 BIT(SIR_MAC_MGMT_PROBE_REQ),
369 },
370 [NL80211_IFTYPE_P2P_GO] = {
371 /* This is also same as for SoftAP */
372 .tx = 0xffff,
373 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ) |
376 BIT(SIR_MAC_MGMT_DISASSOC) |
377 BIT(SIR_MAC_MGMT_AUTH) |
378 BIT(SIR_MAC_MGMT_DEAUTH) |
379 BIT(SIR_MAC_MGMT_ACTION),
380 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700381};
382
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800383#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800384static const struct ieee80211_iface_limit
385wlan_hdd_iface_limit[] = {
386 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800387 /* max = 3 ; Our driver create two interfaces during driver init
388 * wlan0 and p2p0 interfaces. p2p0 is considered as station
389 * interface until a group is formed. In JB architecture, once the
390 * group is formed, interface type of p2p0 is changed to P2P GO or
391 * Client.
392 * When supplicant remove the group, it first issue a set interface
393 * cmd to change the mode back to Station. In JB this works fine as
394 * we advertize two station type interface during driver init.
395 * Some vendors create separate interface for P2P GO/Client,
396 * after group formation(Third one). But while group remove
397 * supplicant first tries to change the mode(3rd interface) to STATION
398 * But as we advertized only two sta type interfaces nl80211 was
399 * returning error for the third one which was leading to failure in
400 * delete interface. Ideally while removing the group, supplicant
401 * should not try to change the 3rd interface mode to Station type.
402 * Till we get a fix in wpa_supplicant, we advertize max STA
403 * interface type to 3
404 */
405 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800406 .types = BIT(NL80211_IFTYPE_STATION),
407 },
408 {
409 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700410 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 },
412 {
413 .max = 1,
414 .types = BIT(NL80211_IFTYPE_P2P_GO) |
415 BIT(NL80211_IFTYPE_P2P_CLIENT),
416 },
417};
418
419/* By default, only single channel concurrency is allowed */
420static struct ieee80211_iface_combination
421wlan_hdd_iface_combination = {
422 .limits = wlan_hdd_iface_limit,
423 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800424 /*
425 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
426 * and p2p0 interfaces during driver init
427 * Some vendors create separate interface for P2P operations.
428 * wlan0: STA interface
429 * p2p0: P2P Device interface, action frames goes
430 * through this interface.
431 * p2p-xx: P2P interface, After GO negotiation this interface is
432 * created for p2p operations(GO/CLIENT interface).
433 */
434 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800435 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
436 .beacon_int_infra_match = false,
437};
438#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800439
Jeff Johnson295189b2012-06-20 16:38:30 -0700440static struct cfg80211_ops wlan_hdd_cfg80211_ops;
441
442/* Data rate 100KBPS based on IE Index */
443struct index_data_rate_type
444{
445 v_U8_t beacon_rate_index;
446 v_U16_t supported_rate[4];
447};
448
449/* 11B, 11G Rate table include Basic rate and Extended rate
450 The IDX field is the rate index
451 The HI field is the rate when RSSI is strong or being ignored
452 (in this case we report actual rate)
453 The MID field is the rate when RSSI is moderate
454 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
455 The LO field is the rate when RSSI is low
456 (in this case we don't report rates, actual current rate used)
457 */
458static const struct
459{
460 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700461 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700462} supported_data_rate[] =
463{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700464/* IDX HI HM LM LO (RSSI-based index */
465 {2, { 10, 10, 10, 0}},
466 {4, { 20, 20, 10, 0}},
467 {11, { 55, 20, 10, 0}},
468 {12, { 60, 55, 20, 0}},
469 {18, { 90, 55, 20, 0}},
470 {22, {110, 55, 20, 0}},
471 {24, {120, 90, 60, 0}},
472 {36, {180, 120, 60, 0}},
473 {44, {220, 180, 60, 0}},
474 {48, {240, 180, 90, 0}},
475 {66, {330, 180, 90, 0}},
476 {72, {360, 240, 90, 0}},
477 {96, {480, 240, 120, 0}},
478 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700479};
480
481/* MCS Based rate table */
482static struct index_data_rate_type supported_mcs_rate[] =
483{
484/* MCS L20 L40 S20 S40 */
485 {0, {65, 135, 72, 150}},
486 {1, {130, 270, 144, 300}},
487 {2, {195, 405, 217, 450}},
488 {3, {260, 540, 289, 600}},
489 {4, {390, 810, 433, 900}},
490 {5, {520, 1080, 578, 1200}},
491 {6, {585, 1215, 650, 1350}},
492 {7, {650, 1350, 722, 1500}}
493};
494
Leo Chang6f8870f2013-03-26 18:11:36 -0700495#ifdef WLAN_FEATURE_11AC
496
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530497#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700498
499struct index_vht_data_rate_type
500{
501 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530502 v_U16_t supported_VHT80_rate[2];
503 v_U16_t supported_VHT40_rate[2];
504 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700505};
506
507typedef enum
508{
509 DATA_RATE_11AC_MAX_MCS_7,
510 DATA_RATE_11AC_MAX_MCS_8,
511 DATA_RATE_11AC_MAX_MCS_9,
512 DATA_RATE_11AC_MAX_MCS_NA
513} eDataRate11ACMaxMcs;
514
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530515/* SSID broadcast type */
516typedef enum eSSIDBcastType
517{
518 eBCAST_UNKNOWN = 0,
519 eBCAST_NORMAL = 1,
520 eBCAST_HIDDEN = 2,
521} tSSIDBcastType;
522
Leo Chang6f8870f2013-03-26 18:11:36 -0700523/* MCS Based VHT rate table */
524static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
525{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530526/* MCS L80 S80 L40 S40 L20 S40*/
527 {0, {293, 325}, {135, 150}, {65, 72}},
528 {1, {585, 650}, {270, 300}, {130, 144}},
529 {2, {878, 975}, {405, 450}, {195, 217}},
530 {3, {1170, 1300}, {540, 600}, {260, 289}},
531 {4, {1755, 1950}, {810, 900}, {390, 433}},
532 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
533 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
534 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
535 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
536 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700537};
538#endif /* WLAN_FEATURE_11AC */
539
c_hpothu79aab322014-07-14 21:11:01 +0530540/*array index points to MCS and array value points respective rssi*/
541static int rssiMcsTbl[][10] =
542{
543/*MCS 0 1 2 3 4 5 6 7 8 9*/
544 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
545 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
546 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
547};
548
Jeff Johnson295189b2012-06-20 16:38:30 -0700549extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530550#ifdef FEATURE_WLAN_SCAN_PNO
551static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
552#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700553
Leo Chang9056f462013-08-01 19:21:11 -0700554#ifdef WLAN_NL80211_TESTMODE
555enum wlan_hdd_tm_attr
556{
557 WLAN_HDD_TM_ATTR_INVALID = 0,
558 WLAN_HDD_TM_ATTR_CMD = 1,
559 WLAN_HDD_TM_ATTR_DATA = 2,
560 WLAN_HDD_TM_ATTR_TYPE = 3,
561 /* keep last */
562 WLAN_HDD_TM_ATTR_AFTER_LAST,
563 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
564};
565
566enum wlan_hdd_tm_cmd
567{
568 WLAN_HDD_TM_CMD_WLAN_HB = 1,
569};
570
571#define WLAN_HDD_TM_DATA_MAX_LEN 5000
572
573static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
574{
575 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
576 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
577 .len = WLAN_HDD_TM_DATA_MAX_LEN },
578};
579#endif /* WLAN_NL80211_TESTMODE */
580
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800581#ifdef FEATURE_WLAN_CH_AVOID
582/*
583 * FUNCTION: wlan_hdd_send_avoid_freq_event
584 * This is called when wlan driver needs to send vendor specific
585 * avoid frequency range event to userspace
586 */
587int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
588 tHddAvoidFreqList *pAvoidFreqList)
589{
590 struct sk_buff *vendor_event;
591
592 ENTER();
593
594 if (!pHddCtx)
595 {
596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
597 "%s: HDD context is null", __func__);
598 return -1;
599 }
600
601 if (!pAvoidFreqList)
602 {
603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
604 "%s: pAvoidFreqList is null", __func__);
605 return -1;
606 }
607
608 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530609#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
610 NULL,
611#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800612 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530613 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800614 GFP_KERNEL);
615 if (!vendor_event)
616 {
617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
618 "%s: cfg80211_vendor_event_alloc failed", __func__);
619 return -1;
620 }
621
622 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
623 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
624
625 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
626
627 EXIT();
628 return 0;
629}
630#endif /* FEATURE_WLAN_CH_AVOID */
631
Srinivas Dasari030bad32015-02-18 23:23:54 +0530632/*
633 * FUNCTION: __wlan_hdd_cfg80211_nan_request
634 * This is called when wlan driver needs to send vendor specific
635 * nan request event.
636 */
637static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
638 struct wireless_dev *wdev,
639 const void *data, int data_len)
640{
641 tNanRequestReq nan_req;
642 VOS_STATUS status;
643 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530644 struct net_device *dev = wdev->netdev;
645 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
646 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530647 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
648
649 if (0 == data_len)
650 {
651 hddLog(VOS_TRACE_LEVEL_ERROR,
652 FL("NAN - Invalid Request, length = 0"));
653 return ret_val;
654 }
655
656 if (NULL == data)
657 {
658 hddLog(VOS_TRACE_LEVEL_ERROR,
659 FL("NAN - Invalid Request, data is NULL"));
660 return ret_val;
661 }
662
663 status = wlan_hdd_validate_context(pHddCtx);
664 if (0 != status)
665 {
666 hddLog(VOS_TRACE_LEVEL_ERROR,
667 FL("HDD context is not valid"));
668 return -EINVAL;
669 }
670
671 hddLog(LOG1, FL("Received NAN command"));
672 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
673 (tANI_U8 *)data, data_len);
674
675 /* check the NAN Capability */
676 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
677 {
678 hddLog(VOS_TRACE_LEVEL_ERROR,
679 FL("NAN is not supported by Firmware"));
680 return -EINVAL;
681 }
682
683 nan_req.request_data_len = data_len;
684 nan_req.request_data = data;
685
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530686 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530687 if (VOS_STATUS_SUCCESS == status)
688 {
689 ret_val = 0;
690 }
691 return ret_val;
692}
693
694/*
695 * FUNCTION: wlan_hdd_cfg80211_nan_request
696 * Wrapper to protect the nan vendor command from ssr
697 */
698static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
699 struct wireless_dev *wdev,
700 const void *data, int data_len)
701{
702 int ret;
703
704 vos_ssr_protect(__func__);
705 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
706 vos_ssr_unprotect(__func__);
707
708 return ret;
709}
710
711/*
712 * FUNCTION: wlan_hdd_cfg80211_nan_callback
713 * This is a callback function and it gets called
714 * when we need to report nan response event to
715 * upper layers.
716 */
717static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
718{
719 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
720 struct sk_buff *vendor_event;
721 int status;
722 tSirNanEvent *data;
723
724 ENTER();
725 if (NULL == msg)
726 {
727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
728 FL(" msg received here is null"));
729 return;
730 }
731 data = msg;
732
733 status = wlan_hdd_validate_context(pHddCtx);
734
735 if (0 != status)
736 {
737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
738 FL("HDD context is not valid"));
739 return;
740 }
741
742 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530743#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
744 NULL,
745#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530746 data->event_data_len +
747 NLMSG_HDRLEN,
748 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
749 GFP_KERNEL);
750
751 if (!vendor_event)
752 {
753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
754 FL("cfg80211_vendor_event_alloc failed"));
755 return;
756 }
757 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
758 data->event_data_len, data->event_data))
759 {
760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
761 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
762 kfree_skb(vendor_event);
763 return;
764 }
765 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
766 EXIT();
767}
768
769/*
770 * FUNCTION: wlan_hdd_cfg80211_nan_init
771 * This function is called to register the callback to sme layer
772 */
773inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
774{
775 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
776}
777
778
Sunil Duttc69bccb2014-05-26 21:30:20 +0530779#ifdef WLAN_FEATURE_LINK_LAYER_STATS
780
781static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
782 struct sk_buff *vendor_event)
783{
784 if (nla_put_u8(vendor_event,
785 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
786 stats->rate.preamble) ||
787 nla_put_u8(vendor_event,
788 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
789 stats->rate.nss) ||
790 nla_put_u8(vendor_event,
791 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
792 stats->rate.bw) ||
793 nla_put_u8(vendor_event,
794 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
795 stats->rate.rateMcsIdx) ||
796 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
797 stats->rate.bitrate ) ||
798 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
799 stats->txMpdu ) ||
800 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
801 stats->rxMpdu ) ||
802 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
803 stats->mpduLost ) ||
804 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
805 stats->retries) ||
806 nla_put_u32(vendor_event,
807 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
808 stats->retriesShort ) ||
809 nla_put_u32(vendor_event,
810 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
811 stats->retriesLong))
812 {
813 hddLog(VOS_TRACE_LEVEL_ERROR,
814 FL("QCA_WLAN_VENDOR_ATTR put fail"));
815 return FALSE;
816 }
817 return TRUE;
818}
819
820static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
821 struct sk_buff *vendor_event)
822{
823 u32 i = 0;
824 struct nlattr *rateInfo;
825 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
826 stats->type) ||
827 nla_put(vendor_event,
828 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
829 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
830 nla_put_u32(vendor_event,
831 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
832 stats->capabilities) ||
833 nla_put_u32(vendor_event,
834 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
835 stats->numRate))
836 {
837 hddLog(VOS_TRACE_LEVEL_ERROR,
838 FL("QCA_WLAN_VENDOR_ATTR put fail"));
839 goto error;
840 }
841
842 rateInfo = nla_nest_start(vendor_event,
843 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530844 if(!rateInfo)
845 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530846 for (i = 0; i < stats->numRate; i++)
847 {
848 struct nlattr *rates;
849 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
850 stats->rateStats +
851 (i * sizeof(tSirWifiRateStat)));
852 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530853 if(!rates)
854 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530855
856 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
857 {
858 hddLog(VOS_TRACE_LEVEL_ERROR,
859 FL("QCA_WLAN_VENDOR_ATTR put fail"));
860 return FALSE;
861 }
862 nla_nest_end(vendor_event, rates);
863 }
864 nla_nest_end(vendor_event, rateInfo);
865
866 return TRUE;
867error:
868 return FALSE;
869}
870
871static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
872 struct sk_buff *vendor_event)
873{
874 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
875 stats->ac ) ||
876 nla_put_u32(vendor_event,
877 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
878 stats->txMpdu ) ||
879 nla_put_u32(vendor_event,
880 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
881 stats->rxMpdu ) ||
882 nla_put_u32(vendor_event,
883 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
884 stats->txMcast ) ||
885 nla_put_u32(vendor_event,
886 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
887 stats->rxMcast ) ||
888 nla_put_u32(vendor_event,
889 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
890 stats->rxAmpdu ) ||
891 nla_put_u32(vendor_event,
892 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
893 stats->txAmpdu ) ||
894 nla_put_u32(vendor_event,
895 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
896 stats->mpduLost )||
897 nla_put_u32(vendor_event,
898 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
899 stats->retries ) ||
900 nla_put_u32(vendor_event,
901 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
902 stats->retriesShort ) ||
903 nla_put_u32(vendor_event,
904 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
905 stats->retriesLong ) ||
906 nla_put_u32(vendor_event,
907 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
908 stats->contentionTimeMin ) ||
909 nla_put_u32(vendor_event,
910 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
911 stats->contentionTimeMax ) ||
912 nla_put_u32(vendor_event,
913 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
914 stats->contentionTimeAvg ) ||
915 nla_put_u32(vendor_event,
916 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
917 stats->contentionNumSamples ))
918 {
919 hddLog(VOS_TRACE_LEVEL_ERROR,
920 FL("QCA_WLAN_VENDOR_ATTR put fail") );
921 return FALSE;
922 }
923 return TRUE;
924}
925
926static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
927 struct sk_buff *vendor_event)
928{
Dino Myclec8f3f332014-07-21 16:48:27 +0530929 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530930 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
931 nla_put(vendor_event,
932 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
933 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
934 nla_put_u32(vendor_event,
935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
936 stats->state ) ||
937 nla_put_u32(vendor_event,
938 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
939 stats->roaming ) ||
940 nla_put_u32(vendor_event,
941 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
942 stats->capabilities ) ||
943 nla_put(vendor_event,
944 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
945 strlen(stats->ssid), stats->ssid) ||
946 nla_put(vendor_event,
947 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
948 WNI_CFG_BSSID_LEN, stats->bssid) ||
949 nla_put(vendor_event,
950 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
951 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
952 nla_put(vendor_event,
953 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
954 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
955 )
956 {
957 hddLog(VOS_TRACE_LEVEL_ERROR,
958 FL("QCA_WLAN_VENDOR_ATTR put fail") );
959 return FALSE;
960 }
961 return TRUE;
962}
963
Dino Mycle3b9536d2014-07-09 22:05:24 +0530964static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
965 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530966 struct sk_buff *vendor_event)
967{
968 int i = 0;
969 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530970 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
971 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530972 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530973
Sunil Duttc69bccb2014-05-26 21:30:20 +0530974 if (FALSE == put_wifi_interface_info(
975 &pWifiIfaceStat->info,
976 vendor_event))
977 {
978 hddLog(VOS_TRACE_LEVEL_ERROR,
979 FL("QCA_WLAN_VENDOR_ATTR put fail") );
980 return FALSE;
981
982 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530983 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
984 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
985 if (NULL == pWifiIfaceStatTL)
986 {
987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
988 return FALSE;
989 }
990
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530991 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
992 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
993 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
994 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
995
996 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
997 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
998 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
999 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301000
1001 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1002 {
1003 if (VOS_STATUS_SUCCESS ==
1004 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1005 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1006 {
1007 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1008 * obtained from TL structure
1009 */
1010
1011 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1012 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301013 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1014
Srinivas Dasari98947432014-11-07 19:41:24 +05301015 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1016 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1017 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1018 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1019 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1020 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1021 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1022 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301023
Srinivas Dasari98947432014-11-07 19:41:24 +05301024 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1025 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1026 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1027 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1028 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1029 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1030 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1031 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301032
Srinivas Dasari98947432014-11-07 19:41:24 +05301033 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1034 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1035 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1036 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1037 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1038 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1039 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1040 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301041 }
1042 else
1043 {
1044 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1045 }
1046
Dino Mycle3b9536d2014-07-09 22:05:24 +05301047 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1048 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1049 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1050 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1051 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1052 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1053 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1054 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1055 }
1056 else
1057 {
1058 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1059 }
1060
1061
Sunil Duttc69bccb2014-05-26 21:30:20 +05301062
1063 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301064 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1065 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1066 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301067 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1068 pWifiIfaceStat->beaconRx) ||
1069 nla_put_u32(vendor_event,
1070 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1071 pWifiIfaceStat->mgmtRx) ||
1072 nla_put_u32(vendor_event,
1073 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1074 pWifiIfaceStat->mgmtActionRx) ||
1075 nla_put_u32(vendor_event,
1076 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1077 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301078 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301079 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1080 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301081 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301082 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1083 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301084 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301085 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1086 pWifiIfaceStat->rssiAck))
1087 {
1088 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301089 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1090 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301091 return FALSE;
1092 }
1093
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301094#ifdef FEATURE_EXT_LL_STAT
1095 /*
1096 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1097 * then host should send Leaky AP stats to upper layer,
1098 * otherwise no need to send these stats.
1099 */
1100 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1101 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1102 )
1103 {
1104 hddLog(VOS_TRACE_LEVEL_INFO,
1105 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1106 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1107 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1108 pWifiIfaceStat->leakyApStat.rx_leak_window,
1109 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1110 if (nla_put_u32(vendor_event,
1111 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1112 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1113 nla_put_u32(vendor_event,
1114 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1115 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1116 nla_put_u32(vendor_event,
1117 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1118 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1119 nla_put_u64(vendor_event,
1120 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1121 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1122 {
1123 hddLog(VOS_TRACE_LEVEL_ERROR,
1124 FL("EXT_LL_STAT put fail"));
1125 vos_mem_free(pWifiIfaceStatTL);
1126 return FALSE;
1127 }
1128 }
1129#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301130 wmmInfo = nla_nest_start(vendor_event,
1131 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301132 if(!wmmInfo)
1133 {
1134 vos_mem_free(pWifiIfaceStatTL);
1135 return FALSE;
1136 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301137 for (i = 0; i < WIFI_AC_MAX; i++)
1138 {
1139 struct nlattr *wmmStats;
1140 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301141 if(!wmmStats)
1142 {
1143 vos_mem_free(pWifiIfaceStatTL);
1144 return FALSE;
1145 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301146 if (FALSE == put_wifi_wmm_ac_stat(
1147 &pWifiIfaceStat->AccessclassStats[i],
1148 vendor_event))
1149 {
1150 hddLog(VOS_TRACE_LEVEL_ERROR,
1151 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301152 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301153 return FALSE;
1154 }
1155
1156 nla_nest_end(vendor_event, wmmStats);
1157 }
1158 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301159 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301160 return TRUE;
1161}
1162
1163static tSirWifiInterfaceMode
1164 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1165{
1166 switch (deviceMode)
1167 {
1168 case WLAN_HDD_INFRA_STATION:
1169 return WIFI_INTERFACE_STA;
1170 case WLAN_HDD_SOFTAP:
1171 return WIFI_INTERFACE_SOFTAP;
1172 case WLAN_HDD_P2P_CLIENT:
1173 return WIFI_INTERFACE_P2P_CLIENT;
1174 case WLAN_HDD_P2P_GO:
1175 return WIFI_INTERFACE_P2P_GO;
1176 case WLAN_HDD_IBSS:
1177 return WIFI_INTERFACE_IBSS;
1178 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301179 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301180 }
1181}
1182
1183static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1184 tpSirWifiInterfaceInfo pInfo)
1185{
1186 v_U8_t *staMac = NULL;
1187 hdd_station_ctx_t *pHddStaCtx;
1188 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1189 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1190
1191 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1192
1193 vos_mem_copy(pInfo->macAddr,
1194 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1195
1196 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1197 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1198 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1199 {
1200 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1201 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1202 {
1203 pInfo->state = WIFI_DISCONNECTED;
1204 }
1205 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1206 {
1207 hddLog(VOS_TRACE_LEVEL_ERROR,
1208 "%s: Session ID %d, Connection is in progress", __func__,
1209 pAdapter->sessionId);
1210 pInfo->state = WIFI_ASSOCIATING;
1211 }
1212 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1213 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1214 {
1215 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1216 hddLog(VOS_TRACE_LEVEL_ERROR,
1217 "%s: client " MAC_ADDRESS_STR
1218 " is in the middle of WPS/EAPOL exchange.", __func__,
1219 MAC_ADDR_ARRAY(staMac));
1220 pInfo->state = WIFI_AUTHENTICATING;
1221 }
1222 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1223 {
1224 pInfo->state = WIFI_ASSOCIATED;
1225 vos_mem_copy(pInfo->bssid,
1226 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1227 vos_mem_copy(pInfo->ssid,
1228 pHddStaCtx->conn_info.SSID.SSID.ssId,
1229 pHddStaCtx->conn_info.SSID.SSID.length);
1230 //NULL Terminate the string.
1231 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1232 }
1233 }
1234 vos_mem_copy(pInfo->countryStr,
1235 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1236
1237 vos_mem_copy(pInfo->apCountryStr,
1238 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1239
1240 return TRUE;
1241}
1242
1243/*
1244 * hdd_link_layer_process_peer_stats () - This function is called after
1245 * receiving Link Layer Peer statistics from FW.This function converts
1246 * the firmware data to the NL data and sends the same to the kernel/upper
1247 * layers.
1248 */
1249static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1250 v_VOID_t *pData)
1251{
1252 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301253 tpSirWifiPeerStat pWifiPeerStat;
1254 tpSirWifiPeerInfo pWifiPeerInfo;
1255 struct nlattr *peerInfo;
1256 struct sk_buff *vendor_event;
1257 int status, i;
1258
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301259 ENTER();
1260
Sunil Duttc69bccb2014-05-26 21:30:20 +05301261 status = wlan_hdd_validate_context(pHddCtx);
1262 if (0 != status)
1263 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301264 return;
1265 }
1266
1267 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1268
1269 hddLog(VOS_TRACE_LEVEL_INFO,
1270 "LL_STATS_PEER_ALL : numPeers %u",
1271 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301272 /*
1273 * Allocate a size of 4096 for the peer stats comprising
1274 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1275 * sizeof (tSirWifiRateStat).Each field is put with an
1276 * NL attribute.The size of 4096 is considered assuming
1277 * that number of rates shall not exceed beyond 50 with
1278 * the sizeof (tSirWifiRateStat) being 32.
1279 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301280 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1281 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301282 if (!vendor_event)
1283 {
1284 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301285 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301286 __func__);
1287 return;
1288 }
1289 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301290 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1291 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1292 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301293 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1294 pWifiPeerStat->numPeers))
1295 {
1296 hddLog(VOS_TRACE_LEVEL_ERROR,
1297 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1298 kfree_skb(vendor_event);
1299 return;
1300 }
1301
1302 peerInfo = nla_nest_start(vendor_event,
1303 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301304 if(!peerInfo)
1305 {
1306 hddLog(VOS_TRACE_LEVEL_ERROR,
1307 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1308 __func__);
1309 kfree_skb(vendor_event);
1310 return;
1311 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301312
1313 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1314 pWifiPeerStat->peerInfo);
1315
1316 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1317 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301318 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301319 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301320
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301321 if(!peers)
1322 {
1323 hddLog(VOS_TRACE_LEVEL_ERROR,
1324 "%s: peer stats put fail",
1325 __func__);
1326 kfree_skb(vendor_event);
1327 return;
1328 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301329 if (FALSE == put_wifi_peer_info(
1330 pWifiPeerInfo, vendor_event))
1331 {
1332 hddLog(VOS_TRACE_LEVEL_ERROR,
1333 "%s: put_wifi_peer_info put fail", __func__);
1334 kfree_skb(vendor_event);
1335 return;
1336 }
1337
1338 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1339 pWifiPeerStat->peerInfo +
1340 (i * sizeof(tSirWifiPeerInfo)) +
1341 (numRate * sizeof (tSirWifiRateStat)));
1342 nla_nest_end(vendor_event, peers);
1343 }
1344 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301345 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301346 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301347}
1348
1349/*
1350 * hdd_link_layer_process_iface_stats () - This function is called after
1351 * receiving Link Layer Interface statistics from FW.This function converts
1352 * the firmware data to the NL data and sends the same to the kernel/upper
1353 * layers.
1354 */
1355static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1356 v_VOID_t *pData)
1357{
1358 tpSirWifiIfaceStat pWifiIfaceStat;
1359 struct sk_buff *vendor_event;
1360 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1361 int status;
1362
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301363 ENTER();
1364
Sunil Duttc69bccb2014-05-26 21:30:20 +05301365 status = wlan_hdd_validate_context(pHddCtx);
1366 if (0 != status)
1367 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301368 return;
1369 }
1370 /*
1371 * Allocate a size of 4096 for the interface stats comprising
1372 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1373 * assuming that all these fit with in the limit.Please take
1374 * a call on the limit based on the data requirements on
1375 * interface statistics.
1376 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301377 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1378 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301379 if (!vendor_event)
1380 {
1381 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301382 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301383 return;
1384 }
1385
1386 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1387
Dino Mycle3b9536d2014-07-09 22:05:24 +05301388
1389 if (FALSE == hdd_get_interface_info( pAdapter,
1390 &pWifiIfaceStat->info))
1391 {
1392 hddLog(VOS_TRACE_LEVEL_ERROR,
1393 FL("hdd_get_interface_info get fail") );
1394 kfree_skb(vendor_event);
1395 return;
1396 }
1397
1398 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1399 vendor_event))
1400 {
1401 hddLog(VOS_TRACE_LEVEL_ERROR,
1402 FL("put_wifi_iface_stats fail") );
1403 kfree_skb(vendor_event);
1404 return;
1405 }
1406
Sunil Duttc69bccb2014-05-26 21:30:20 +05301407 hddLog(VOS_TRACE_LEVEL_INFO,
1408 "WMI_LINK_STATS_IFACE Data");
1409
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301410 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301411
1412 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301413}
1414
1415/*
1416 * hdd_link_layer_process_radio_stats () - This function is called after
1417 * receiving Link Layer Radio statistics from FW.This function converts
1418 * the firmware data to the NL data and sends the same to the kernel/upper
1419 * layers.
1420 */
1421static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1422 v_VOID_t *pData)
1423{
1424 int status, i;
1425 tpSirWifiRadioStat pWifiRadioStat;
1426 tpSirWifiChannelStats pWifiChannelStats;
1427 struct sk_buff *vendor_event;
1428 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1429 struct nlattr *chList;
1430
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301431 ENTER();
1432
Sunil Duttc69bccb2014-05-26 21:30:20 +05301433 status = wlan_hdd_validate_context(pHddCtx);
1434 if (0 != status)
1435 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301436 return;
1437 }
1438 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1439
1440 hddLog(VOS_TRACE_LEVEL_INFO,
1441 "LL_STATS_RADIO"
1442 " radio is %d onTime is %u "
1443 " txTime is %u rxTime is %u "
1444 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301445 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301446 " onTimePnoScan is %u onTimeHs20 is %u "
1447 " numChannels is %u",
1448 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1449 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1450 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301451 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301452 pWifiRadioStat->onTimeRoamScan,
1453 pWifiRadioStat->onTimePnoScan,
1454 pWifiRadioStat->onTimeHs20,
1455 pWifiRadioStat->numChannels);
1456 /*
1457 * Allocate a size of 4096 for the Radio stats comprising
1458 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1459 * (tSirWifiChannelStats).Each channel data is put with an
1460 * NL attribute.The size of 4096 is considered assuming that
1461 * number of channels shall not exceed beyond 60 with the
1462 * sizeof (tSirWifiChannelStats) being 24 bytes.
1463 */
1464
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301465 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1466 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301467 if (!vendor_event)
1468 {
1469 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301470 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301471 return;
1472 }
1473
1474 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301475 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1476 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1477 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301478 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1479 pWifiRadioStat->radio) ||
1480 nla_put_u32(vendor_event,
1481 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1482 pWifiRadioStat->onTime) ||
1483 nla_put_u32(vendor_event,
1484 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1485 pWifiRadioStat->txTime) ||
1486 nla_put_u32(vendor_event,
1487 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1488 pWifiRadioStat->rxTime) ||
1489 nla_put_u32(vendor_event,
1490 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1491 pWifiRadioStat->onTimeScan) ||
1492 nla_put_u32(vendor_event,
1493 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1494 pWifiRadioStat->onTimeNbd) ||
1495 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301496 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1497 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301498 nla_put_u32(vendor_event,
1499 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1500 pWifiRadioStat->onTimeRoamScan) ||
1501 nla_put_u32(vendor_event,
1502 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1503 pWifiRadioStat->onTimePnoScan) ||
1504 nla_put_u32(vendor_event,
1505 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1506 pWifiRadioStat->onTimeHs20) ||
1507 nla_put_u32(vendor_event,
1508 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1509 pWifiRadioStat->numChannels))
1510 {
1511 hddLog(VOS_TRACE_LEVEL_ERROR,
1512 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1513 kfree_skb(vendor_event);
1514 return ;
1515 }
1516
1517 chList = nla_nest_start(vendor_event,
1518 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301519 if(!chList)
1520 {
1521 hddLog(VOS_TRACE_LEVEL_ERROR,
1522 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1523 __func__);
1524 kfree_skb(vendor_event);
1525 return;
1526 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301527 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1528 {
1529 struct nlattr *chInfo;
1530
1531 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1532 pWifiRadioStat->channels +
1533 (i * sizeof(tSirWifiChannelStats)));
1534
Sunil Duttc69bccb2014-05-26 21:30:20 +05301535 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301536 if(!chInfo)
1537 {
1538 hddLog(VOS_TRACE_LEVEL_ERROR,
1539 "%s: failed to put chInfo",
1540 __func__);
1541 kfree_skb(vendor_event);
1542 return;
1543 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301544
1545 if (nla_put_u32(vendor_event,
1546 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1547 pWifiChannelStats->channel.width) ||
1548 nla_put_u32(vendor_event,
1549 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1550 pWifiChannelStats->channel.centerFreq) ||
1551 nla_put_u32(vendor_event,
1552 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1553 pWifiChannelStats->channel.centerFreq0) ||
1554 nla_put_u32(vendor_event,
1555 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1556 pWifiChannelStats->channel.centerFreq1) ||
1557 nla_put_u32(vendor_event,
1558 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1559 pWifiChannelStats->onTime) ||
1560 nla_put_u32(vendor_event,
1561 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1562 pWifiChannelStats->ccaBusyTime))
1563 {
1564 hddLog(VOS_TRACE_LEVEL_ERROR,
1565 FL("cfg80211_vendor_event_alloc failed") );
1566 kfree_skb(vendor_event);
1567 return ;
1568 }
1569 nla_nest_end(vendor_event, chInfo);
1570 }
1571 nla_nest_end(vendor_event, chList);
1572
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301573 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301574
1575 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301576 return;
1577}
1578
1579/*
1580 * hdd_link_layer_stats_ind_callback () - This function is called after
1581 * receiving Link Layer indications from FW.This callback converts the firmware
1582 * data to the NL data and send the same to the kernel/upper layers.
1583 */
1584static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1585 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301586 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301587{
Dino Mycled3d50022014-07-07 12:58:25 +05301588 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1589 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301590 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301591 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301592 int status;
1593
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301594 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301595
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301596 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301597 if (0 != status)
1598 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301599 return;
1600 }
1601
Dino Mycled3d50022014-07-07 12:58:25 +05301602 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1603 if (NULL == pAdapter)
1604 {
1605 hddLog(VOS_TRACE_LEVEL_ERROR,
1606 FL(" MAC address %pM does not exist with host"),
1607 macAddr);
1608 return;
1609 }
1610
Sunil Duttc69bccb2014-05-26 21:30:20 +05301611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301612 "%s: Interface: %s LLStats indType: %d", __func__,
1613 pAdapter->dev->name, indType);
1614
Sunil Duttc69bccb2014-05-26 21:30:20 +05301615 switch (indType)
1616 {
1617 case SIR_HAL_LL_STATS_RESULTS_RSP:
1618 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301619 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301620 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1621 "respId = %u, moreResultToFollow = %u",
1622 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1623 macAddr, linkLayerStatsResults->respId,
1624 linkLayerStatsResults->moreResultToFollow);
1625
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301626 spin_lock(&hdd_context_lock);
1627 context = &pHddCtx->ll_stats_context;
1628 /* validate response received from target */
1629 if ((context->request_id != linkLayerStatsResults->respId) ||
1630 !(context->request_bitmap & linkLayerStatsResults->paramId))
1631 {
1632 spin_unlock(&hdd_context_lock);
1633 hddLog(LOGE,
1634 FL("Error : Request id %d response id %d request bitmap 0x%x"
1635 "response bitmap 0x%x"),
1636 context->request_id, linkLayerStatsResults->respId,
1637 context->request_bitmap, linkLayerStatsResults->paramId);
1638 return;
1639 }
1640 spin_unlock(&hdd_context_lock);
1641
Sunil Duttc69bccb2014-05-26 21:30:20 +05301642 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1643 {
1644 hdd_link_layer_process_radio_stats(pAdapter,
1645 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301646 spin_lock(&hdd_context_lock);
1647 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1648 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301649 }
1650 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1651 {
1652 hdd_link_layer_process_iface_stats(pAdapter,
1653 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301654 spin_lock(&hdd_context_lock);
1655 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1656 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301657 }
1658 else if ( linkLayerStatsResults->paramId &
1659 WMI_LINK_STATS_ALL_PEER )
1660 {
1661 hdd_link_layer_process_peer_stats(pAdapter,
1662 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301663 spin_lock(&hdd_context_lock);
1664 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1665 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301666 } /* WMI_LINK_STATS_ALL_PEER */
1667 else
1668 {
1669 hddLog(VOS_TRACE_LEVEL_ERROR,
1670 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1671 }
1672
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301673 spin_lock(&hdd_context_lock);
1674 /* complete response event if all requests are completed */
1675 if (0 == context->request_bitmap)
1676 complete(&context->response_event);
1677 spin_unlock(&hdd_context_lock);
1678
Sunil Duttc69bccb2014-05-26 21:30:20 +05301679 break;
1680 }
1681 default:
1682 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1683 break;
1684 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301685
1686 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301687 return;
1688}
1689
1690const struct
1691nla_policy
1692qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1693{
1694 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1695 { .type = NLA_U32 },
1696 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1697 { .type = NLA_U32 },
1698};
1699
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301700static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1701 struct wireless_dev *wdev,
1702 const void *data,
1703 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301704{
1705 int status;
1706 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301707 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301708 struct net_device *dev = wdev->netdev;
1709 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1710 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1711
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301712 ENTER();
1713
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714 status = wlan_hdd_validate_context(pHddCtx);
1715 if (0 != status)
1716 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301717 return -EINVAL;
1718 }
1719
1720 if (NULL == pAdapter)
1721 {
1722 hddLog(VOS_TRACE_LEVEL_ERROR,
1723 FL("HDD adapter is Null"));
1724 return -ENODEV;
1725 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301726 /* check the LLStats Capability */
1727 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1728 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1729 {
1730 hddLog(VOS_TRACE_LEVEL_ERROR,
1731 FL("Link Layer Statistics not supported by Firmware"));
1732 return -EINVAL;
1733 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301734
1735 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1736 (struct nlattr *)data,
1737 data_len, qca_wlan_vendor_ll_set_policy))
1738 {
1739 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1740 return -EINVAL;
1741 }
1742 if (!tb_vendor
1743 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1744 {
1745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1746 return -EINVAL;
1747 }
1748 if (!tb_vendor[
1749 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1750 {
1751 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1752 return -EINVAL;
1753 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301754 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301755 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301756
Dino Mycledf0a5d92014-07-04 09:41:55 +05301757 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301758 nla_get_u32(
1759 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1760
Dino Mycledf0a5d92014-07-04 09:41:55 +05301761 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301762 nla_get_u32(
1763 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1764
Dino Mycled3d50022014-07-07 12:58:25 +05301765 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1766 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301767
1768
1769 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301770 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1771 "Statistics Gathering = %d ",
1772 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1773 linkLayerStatsSetReq.mpduSizeThreshold,
1774 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301775
1776 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1777 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301778 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301779 {
1780 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1781 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301782 return -EINVAL;
1783
1784 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301785
Sunil Duttc69bccb2014-05-26 21:30:20 +05301786 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301787 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301788 {
1789 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1790 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301791 return -EINVAL;
1792 }
1793
1794 pAdapter->isLinkLayerStatsSet = 1;
1795
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301796 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301797 return 0;
1798}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301799static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1800 struct wireless_dev *wdev,
1801 const void *data,
1802 int data_len)
1803{
1804 int ret = 0;
1805
1806 vos_ssr_protect(__func__);
1807 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1808 vos_ssr_unprotect(__func__);
1809
1810 return ret;
1811}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301812
1813const struct
1814nla_policy
1815qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1816{
1817 /* Unsigned 32bit value provided by the caller issuing the GET stats
1818 * command. When reporting
1819 * the stats results, the driver uses the same value to indicate
1820 * which GET request the results
1821 * correspond to.
1822 */
1823 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1824
1825 /* Unsigned 32bit value . bit mask to identify what statistics are
1826 requested for retrieval */
1827 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1828};
1829
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301830static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1831 struct wireless_dev *wdev,
1832 const void *data,
1833 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301834{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301835 unsigned long rc;
1836 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301837 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1838 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301839 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301840 struct net_device *dev = wdev->netdev;
1841 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301842 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301843 int status;
1844
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301845 ENTER();
1846
Sunil Duttc69bccb2014-05-26 21:30:20 +05301847 status = wlan_hdd_validate_context(pHddCtx);
1848 if (0 != status)
1849 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301850 return -EINVAL ;
1851 }
1852
1853 if (NULL == pAdapter)
1854 {
1855 hddLog(VOS_TRACE_LEVEL_FATAL,
1856 "%s: HDD adapter is Null", __func__);
1857 return -ENODEV;
1858 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301859
1860 if (pHddStaCtx == NULL)
1861 {
1862 hddLog(VOS_TRACE_LEVEL_FATAL,
1863 "%s: HddStaCtx is Null", __func__);
1864 return -ENODEV;
1865 }
1866
Dino Mycledf0a5d92014-07-04 09:41:55 +05301867 /* check the LLStats Capability */
1868 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1869 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1870 {
1871 hddLog(VOS_TRACE_LEVEL_ERROR,
1872 FL("Link Layer Statistics not supported by Firmware"));
1873 return -EINVAL;
1874 }
1875
Sunil Duttc69bccb2014-05-26 21:30:20 +05301876
1877 if (!pAdapter->isLinkLayerStatsSet)
1878 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05301879 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301880 "%s: isLinkLayerStatsSet : %d",
1881 __func__, pAdapter->isLinkLayerStatsSet);
1882 return -EINVAL;
1883 }
1884
Mukul Sharma10313ba2015-07-29 19:14:39 +05301885 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1886 {
1887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1888 "%s: Roaming in progress, so unable to proceed this request", __func__);
1889 return -EBUSY;
1890 }
1891
Sunil Duttc69bccb2014-05-26 21:30:20 +05301892 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1893 (struct nlattr *)data,
1894 data_len, qca_wlan_vendor_ll_get_policy))
1895 {
1896 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1897 return -EINVAL;
1898 }
1899
1900 if (!tb_vendor
1901 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1902 {
1903 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1904 return -EINVAL;
1905 }
1906
1907 if (!tb_vendor
1908 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1909 {
1910 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1911 return -EINVAL;
1912 }
1913
Sunil Duttc69bccb2014-05-26 21:30:20 +05301914
Dino Mycledf0a5d92014-07-04 09:41:55 +05301915 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 nla_get_u32( tb_vendor[
1917 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301918 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919 nla_get_u32( tb_vendor[
1920 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1921
Dino Mycled3d50022014-07-07 12:58:25 +05301922 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1923 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301924
1925 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301926 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1927 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301928 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301929
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301930 spin_lock(&hdd_context_lock);
1931 context = &pHddCtx->ll_stats_context;
1932 context->request_id = linkLayerStatsGetReq.reqId;
1933 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1934 INIT_COMPLETION(context->response_event);
1935 spin_unlock(&hdd_context_lock);
1936
Sunil Duttc69bccb2014-05-26 21:30:20 +05301937 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301938 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301939 {
1940 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1941 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301942 return -EINVAL;
1943 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301944
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301945 rc = wait_for_completion_timeout(&context->response_event,
1946 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1947 if (!rc)
1948 {
1949 hddLog(LOGE,
1950 FL("Target response timed out request id %d request bitmap 0x%x"),
1951 context->request_id, context->request_bitmap);
1952 return -ETIMEDOUT;
1953 }
1954
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301955 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301956 return 0;
1957}
1958
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301959static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1960 struct wireless_dev *wdev,
1961 const void *data,
1962 int data_len)
1963{
1964 int ret = 0;
1965
1966 vos_ssr_protect(__func__);
1967 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1968 vos_ssr_unprotect(__func__);
1969
1970 return ret;
1971}
1972
Sunil Duttc69bccb2014-05-26 21:30:20 +05301973const struct
1974nla_policy
1975qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1976{
1977 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1978 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1979 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1980 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1981};
1982
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301983static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1984 struct wireless_dev *wdev,
1985 const void *data,
1986 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301987{
1988 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1989 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301990 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301991 struct net_device *dev = wdev->netdev;
1992 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1993 u32 statsClearReqMask;
1994 u8 stopReq;
1995 int status;
1996
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301997 ENTER();
1998
Sunil Duttc69bccb2014-05-26 21:30:20 +05301999 status = wlan_hdd_validate_context(pHddCtx);
2000 if (0 != status)
2001 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302002 return -EINVAL;
2003 }
2004
2005 if (NULL == pAdapter)
2006 {
2007 hddLog(VOS_TRACE_LEVEL_FATAL,
2008 "%s: HDD adapter is Null", __func__);
2009 return -ENODEV;
2010 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302011 /* check the LLStats Capability */
2012 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2013 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2014 {
2015 hddLog(VOS_TRACE_LEVEL_ERROR,
2016 FL("Enable LLStats Capability"));
2017 return -EINVAL;
2018 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302019
2020 if (!pAdapter->isLinkLayerStatsSet)
2021 {
2022 hddLog(VOS_TRACE_LEVEL_FATAL,
2023 "%s: isLinkLayerStatsSet : %d",
2024 __func__, pAdapter->isLinkLayerStatsSet);
2025 return -EINVAL;
2026 }
2027
2028 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2029 (struct nlattr *)data,
2030 data_len, qca_wlan_vendor_ll_clr_policy))
2031 {
2032 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2033 return -EINVAL;
2034 }
2035
2036 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2037
2038 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2039 {
2040 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2041 return -EINVAL;
2042
2043 }
2044
Sunil Duttc69bccb2014-05-26 21:30:20 +05302045
Dino Mycledf0a5d92014-07-04 09:41:55 +05302046 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302047 nla_get_u32(
2048 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2049
Dino Mycledf0a5d92014-07-04 09:41:55 +05302050 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302051 nla_get_u8(
2052 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2053
2054 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302055 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302056
Dino Mycled3d50022014-07-07 12:58:25 +05302057 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2058 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302059
2060 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302061 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2062 "statsClearReqMask = 0x%X, stopReq = %d",
2063 linkLayerStatsClearReq.reqId,
2064 linkLayerStatsClearReq.macAddr,
2065 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302066 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302067
2068 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302069 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302070 {
2071 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302072 hdd_station_ctx_t *pHddStaCtx;
2073
2074 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2075 if (VOS_STATUS_SUCCESS !=
2076 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2077 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2078 {
2079 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2080 "WLANTL_ClearInterfaceStats Failed", __func__);
2081 return -EINVAL;
2082 }
2083 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2084 (statsClearReqMask & WIFI_STATS_IFACE)) {
2085 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2086 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2087 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2088 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2089 }
2090
Sunil Duttc69bccb2014-05-26 21:30:20 +05302091 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2092 2 * sizeof(u32) +
2093 NLMSG_HDRLEN);
2094
2095 if (temp_skbuff != NULL)
2096 {
2097
2098 if (nla_put_u32(temp_skbuff,
2099 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2100 statsClearReqMask) ||
2101 nla_put_u32(temp_skbuff,
2102 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2103 stopReq))
2104 {
2105 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2106 kfree_skb(temp_skbuff);
2107 return -EINVAL;
2108 }
2109 /* If the ask is to stop the stats collection as part of clear
2110 * (stopReq = 1) , ensure that no further requests of get
2111 * go to the firmware by having isLinkLayerStatsSet set to 0.
2112 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302113 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302114 * case the firmware is just asked to clear the statistics.
2115 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302116 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302117 pAdapter->isLinkLayerStatsSet = 0;
2118 return cfg80211_vendor_cmd_reply(temp_skbuff);
2119 }
2120 return -ENOMEM;
2121 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302122
2123 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302124 return -EINVAL;
2125}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302126static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2127 struct wireless_dev *wdev,
2128 const void *data,
2129 int data_len)
2130{
2131 int ret = 0;
2132
2133 vos_ssr_protect(__func__);
2134 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2135 vos_ssr_unprotect(__func__);
2136
2137 return ret;
2138
2139
2140}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2142
Dino Mycle6fb96c12014-06-10 11:52:40 +05302143#ifdef WLAN_FEATURE_EXTSCAN
2144static const struct nla_policy
2145wlan_hdd_extscan_config_policy
2146 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2147{
2148 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2149 { .type = NLA_U32 },
2150 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2151 { .type = NLA_U32 },
2152 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2153 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2154 { .type = NLA_U32 },
2155 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2157
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2159 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2161 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2162 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302163 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2164 { .type = NLA_U32 },
2165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2166 { .type = NLA_U32 },
2167 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2168 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2170 { .type = NLA_U32 },
2171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2172 { .type = NLA_U32 },
2173 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2174 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2176 { .type = NLA_U8 },
2177 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302178 { .type = NLA_U8 },
2179 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2180 { .type = NLA_U8 },
2181 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2182 { .type = NLA_U8 },
2183
2184 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2185 { .type = NLA_U32 },
2186 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2187 { .type = NLA_UNSPEC },
2188 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2189 { .type = NLA_S32 },
2190 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2191 { .type = NLA_S32 },
2192 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2193 { .type = NLA_U32 },
2194 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2195 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302196 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2197 { .type = NLA_U32 },
2198 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2199 { .type = NLA_BINARY,
2200 .len = IEEE80211_MAX_SSID_LEN + 1 },
2201 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302202 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302203 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2204 { .type = NLA_U32 },
2205 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2206 { .type = NLA_U8 },
2207 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2208 { .type = NLA_S32 },
2209 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2210 { .type = NLA_S32 },
2211 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2212 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302213};
2214
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302215/**
2216 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2217 * @ctx: hdd global context
2218 * @data: capabilities data
2219 *
2220 * Return: none
2221 */
2222static void
2223wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302224{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302225 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302226 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302227 tSirEXTScanCapabilitiesEvent *data =
2228 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302229
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302230 ENTER();
2231
2232 if (wlan_hdd_validate_context(pHddCtx))
2233 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302234 return;
2235 }
2236
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302237 if (!pMsg)
2238 {
2239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2240 return;
2241 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302242
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302243 vos_spin_lock_acquire(&hdd_context_lock);
2244
2245 context = &pHddCtx->ext_scan_context;
2246 /* validate response received from target*/
2247 if (context->request_id != data->requestId)
2248 {
2249 vos_spin_lock_release(&hdd_context_lock);
2250 hddLog(LOGE,
2251 FL("Target response id did not match: request_id %d resposne_id %d"),
2252 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302253 return;
2254 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302255 else
2256 {
2257 context->capability_response = *data;
2258 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302259 }
2260
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302261 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302262
Dino Mycle6fb96c12014-06-10 11:52:40 +05302263 return;
2264}
2265
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302266/*
2267 * define short names for the global vendor params
2268 * used by wlan_hdd_send_ext_scan_capability()
2269 */
2270#define PARAM_REQUEST_ID \
2271 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2272#define PARAM_STATUS \
2273 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2274#define MAX_SCAN_CACHE_SIZE \
2275 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2276#define MAX_SCAN_BUCKETS \
2277 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2278#define MAX_AP_CACHE_PER_SCAN \
2279 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2280#define MAX_RSSI_SAMPLE_SIZE \
2281 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2282#define MAX_SCAN_RPT_THRHOLD \
2283 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2284#define MAX_HOTLIST_BSSIDS \
2285 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2286#define MAX_BSSID_HISTORY_ENTRIES \
2287 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2288#define MAX_HOTLIST_SSIDS \
2289 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302290#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2291 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302292
2293static int wlan_hdd_send_ext_scan_capability(void *ctx)
2294{
2295 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2296 struct sk_buff *skb = NULL;
2297 int ret;
2298 tSirEXTScanCapabilitiesEvent *data;
2299 tANI_U32 nl_buf_len;
2300
2301 ret = wlan_hdd_validate_context(pHddCtx);
2302 if (0 != ret)
2303 {
2304 return ret;
2305 }
2306
2307 data = &(pHddCtx->ext_scan_context.capability_response);
2308
2309 nl_buf_len = NLMSG_HDRLEN;
2310 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2311 (sizeof(data->status) + NLA_HDRLEN) +
2312 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2313 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2314 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2315 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2316 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2317 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2318 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2319 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2320
2321 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2322
2323 if (!skb)
2324 {
2325 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2326 return -ENOMEM;
2327 }
2328
2329 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2330 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2331 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2332 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2333 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2334 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2335 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2336 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2337
2338 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2339 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2340 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2341 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2342 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2343 data->maxApPerScan) ||
2344 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2345 data->maxRssiSampleSize) ||
2346 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2347 data->maxScanReportingThreshold) ||
2348 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2349 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2350 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302351 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2352 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302353 {
2354 hddLog(LOGE, FL("nla put fail"));
2355 goto nla_put_failure;
2356 }
2357
2358 cfg80211_vendor_cmd_reply(skb);
2359 return 0;
2360
2361nla_put_failure:
2362 kfree_skb(skb);
2363 return -EINVAL;;
2364}
2365
2366/*
2367 * done with short names for the global vendor params
2368 * used by wlan_hdd_send_ext_scan_capability()
2369 */
2370#undef PARAM_REQUEST_ID
2371#undef PARAM_STATUS
2372#undef MAX_SCAN_CACHE_SIZE
2373#undef MAX_SCAN_BUCKETS
2374#undef MAX_AP_CACHE_PER_SCAN
2375#undef MAX_RSSI_SAMPLE_SIZE
2376#undef MAX_SCAN_RPT_THRHOLD
2377#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302378#undef MAX_BSSID_HISTORY_ENTRIES
2379#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302380
2381static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2382{
2383 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2384 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302385 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302386 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302387
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302388 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302389
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302390 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302391 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302392
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302393 if (!pMsg)
2394 {
2395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302396 return;
2397 }
2398
Dino Mycle6fb96c12014-06-10 11:52:40 +05302399 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2400 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2401
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302402 context = &pHddCtx->ext_scan_context;
2403 spin_lock(&hdd_context_lock);
2404 if (context->request_id == pData->requestId) {
2405 context->response_status = pData->status ? -EINVAL : 0;
2406 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302407 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302408 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302409
2410 /*
2411 * Store the Request ID for comparing with the requestID obtained
2412 * in other requests.HDD shall return a failure is the extscan_stop
2413 * request is issued with a different requestId as that of the
2414 * extscan_start request. Also, This requestId shall be used while
2415 * indicating the full scan results to the upper layers.
2416 * The requestId is stored with the assumption that the firmware
2417 * shall return the ext scan start request's requestId in ext scan
2418 * start response.
2419 */
2420 if (pData->status == 0)
2421 pMac->sme.extScanStartReqId = pData->requestId;
2422
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302423 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302424 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302425}
2426
2427
2428static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2429{
2430 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2431 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302432 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302433
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302434 ENTER();
2435
2436 if (wlan_hdd_validate_context(pHddCtx)){
2437 return;
2438 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302439
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302440 if (!pMsg)
2441 {
2442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302443 return;
2444 }
2445
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302446 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2447 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302448
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302449 context = &pHddCtx->ext_scan_context;
2450 spin_lock(&hdd_context_lock);
2451 if (context->request_id == pData->requestId) {
2452 context->response_status = pData->status ? -EINVAL : 0;
2453 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302454 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302455 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302456
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302457 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302458 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302459}
2460
Dino Mycle6fb96c12014-06-10 11:52:40 +05302461static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2462 void *pMsg)
2463{
2464 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302465 tpSirEXTScanSetBssidHotListRspParams pData =
2466 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302467 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302468
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302469 ENTER();
2470
2471 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302472 return;
2473 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302474
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302475 if (!pMsg)
2476 {
2477 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2478 return;
2479 }
2480
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302481 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2482 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302483
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302484 context = &pHddCtx->ext_scan_context;
2485 spin_lock(&hdd_context_lock);
2486 if (context->request_id == pData->requestId) {
2487 context->response_status = pData->status ? -EINVAL : 0;
2488 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302489 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302490 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302491
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302492 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302493 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302494}
2495
2496static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2497 void *pMsg)
2498{
2499 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302500 tpSirEXTScanResetBssidHotlistRspParams pData =
2501 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302502 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302503
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302504 ENTER();
2505
2506 if (wlan_hdd_validate_context(pHddCtx)) {
2507 return;
2508 }
2509 if (!pMsg)
2510 {
2511 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302512 return;
2513 }
2514
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302515 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2516 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302517
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302518 context = &pHddCtx->ext_scan_context;
2519 spin_lock(&hdd_context_lock);
2520 if (context->request_id == pData->requestId) {
2521 context->response_status = pData->status ? -EINVAL : 0;
2522 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302523 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302524 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302525
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302526 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302527 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302528}
2529
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302530static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2531 void *pMsg)
2532{
2533 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2534 tpSirEXTScanSetSsidHotListRspParams pData =
2535 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2536 struct hdd_ext_scan_context *context;
2537
2538 if (wlan_hdd_validate_context(pHddCtx)){
2539 return;
2540 }
2541
2542 if (!pMsg)
2543 {
2544 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2545 return;
2546 }
2547
2548 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2549 pData->status);
2550
2551 context = &pHddCtx->ext_scan_context;
2552 spin_lock(&hdd_context_lock);
2553 if (context->request_id == pData->requestId) {
2554 context->response_status = pData->status ? -EINVAL : 0;
2555 complete(&context->response_event);
2556 }
2557 spin_unlock(&hdd_context_lock);
2558
2559 return;
2560}
2561
2562static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2563 void *pMsg)
2564{
2565 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2566 tpSirEXTScanResetSsidHotlistRspParams pData =
2567 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2568 struct hdd_ext_scan_context *context;
2569
2570 if (wlan_hdd_validate_context(pHddCtx)) {
2571 return;
2572 }
2573 if (!pMsg)
2574 {
2575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2576 return;
2577 }
2578
2579 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2580 pData->status);
2581
2582 context = &pHddCtx->ext_scan_context;
2583 spin_lock(&hdd_context_lock);
2584 if (context->request_id == pData->requestId) {
2585 context->response_status = pData->status ? -EINVAL : 0;
2586 complete(&context->response_event);
2587 }
2588 spin_unlock(&hdd_context_lock);
2589
2590 return;
2591}
2592
2593
Dino Mycle6fb96c12014-06-10 11:52:40 +05302594static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2595 void *pMsg)
2596{
2597 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2598 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302599 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302600 tANI_S32 totalResults;
2601 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302602 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2603 struct hdd_ext_scan_context *context;
2604 bool ignore_cached_results = false;
2605 tExtscanCachedScanResult *result;
2606 struct nlattr *nla_results;
2607 tANI_U16 ieLength= 0;
2608 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302609
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302610 ENTER();
2611
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302612 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302613 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302614
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302615 if (!pMsg)
2616 {
2617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2618 return;
2619 }
2620
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302621 spin_lock(&hdd_context_lock);
2622 context = &pHddCtx->ext_scan_context;
2623 ignore_cached_results = context->ignore_cached_results;
2624 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302626 if (ignore_cached_results) {
2627 hddLog(LOGE,
2628 FL("Ignore the cached results received after timeout"));
2629 return;
2630 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302631
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302632 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2633 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302634
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302635 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302636
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302637 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2638 scan_id_index++) {
2639 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302640
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302641 totalResults = result->num_results;
2642 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2643 result->scan_id, result->flags, totalResults);
2644 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302645
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302646 do{
2647 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2648 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2649 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302650
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302651 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2652 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2653
2654 if (!skb) {
2655 hddLog(VOS_TRACE_LEVEL_ERROR,
2656 FL("cfg80211_vendor_event_alloc failed"));
2657 return;
2658 }
2659
2660 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2661
2662 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2663 pData->requestId) ||
2664 nla_put_u32(skb,
2665 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2666 resultsPerEvent)) {
2667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2668 goto fail;
2669 }
2670 if (nla_put_u8(skb,
2671 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2672 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302673 {
2674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2675 goto fail;
2676 }
2677
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302678 if (nla_put_u32(skb,
2679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2680 result->scan_id)) {
2681 hddLog(LOGE, FL("put fail"));
2682 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302683 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302684
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302685 nla_results = nla_nest_start(skb,
2686 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2687 if (!nla_results)
2688 goto fail;
2689
2690 if (resultsPerEvent) {
2691 struct nlattr *aps;
2692 struct nlattr *nla_result;
2693
2694 nla_result = nla_nest_start(skb, scan_id_index);
2695 if(!nla_result)
2696 goto fail;
2697
2698 if (nla_put_u32(skb,
2699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2700 result->scan_id) ||
2701 nla_put_u32(skb,
2702 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2703 result->flags) ||
2704 nla_put_u32(skb,
2705 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2706 totalResults)) {
2707 hddLog(LOGE, FL("put fail"));
2708 goto fail;
2709 }
2710
2711 aps = nla_nest_start(skb,
2712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2713 if (!aps)
2714 {
2715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2716 goto fail;
2717 }
2718
2719 head_ptr = (tpSirWifiScanResult) &(result->ap);
2720
2721 for (j = 0; j < resultsPerEvent; j++, i++) {
2722 struct nlattr *ap;
2723 pSirWifiScanResult = head_ptr + i;
2724
2725 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05302726 * Firmware returns timestamp from extscan_start till
2727 * BSSID was cached (in micro seconds). Add this with
2728 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302729 * to derive the time since boot when the
2730 * BSSID was cached.
2731 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05302732 pSirWifiScanResult->ts +=
2733 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302734 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2735 "Ssid (%s)"
2736 "Bssid: %pM "
2737 "Channel (%u)"
2738 "Rssi (%d)"
2739 "RTT (%u)"
2740 "RTT_SD (%u)"
2741 "Beacon Period %u"
2742 "Capability 0x%x "
2743 "Ie length %d",
2744 i,
2745 pSirWifiScanResult->ts,
2746 pSirWifiScanResult->ssid,
2747 pSirWifiScanResult->bssid,
2748 pSirWifiScanResult->channel,
2749 pSirWifiScanResult->rssi,
2750 pSirWifiScanResult->rtt,
2751 pSirWifiScanResult->rtt_sd,
2752 pSirWifiScanResult->beaconPeriod,
2753 pSirWifiScanResult->capability,
2754 ieLength);
2755
2756 ap = nla_nest_start(skb, j + 1);
2757 if (!ap)
2758 {
2759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2760 goto fail;
2761 }
2762
2763 if (nla_put_u64(skb,
2764 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2765 pSirWifiScanResult->ts) )
2766 {
2767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2768 goto fail;
2769 }
2770 if (nla_put(skb,
2771 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2772 sizeof(pSirWifiScanResult->ssid),
2773 pSirWifiScanResult->ssid) )
2774 {
2775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2776 goto fail;
2777 }
2778 if (nla_put(skb,
2779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2780 sizeof(pSirWifiScanResult->bssid),
2781 pSirWifiScanResult->bssid) )
2782 {
2783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2784 goto fail;
2785 }
2786 if (nla_put_u32(skb,
2787 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2788 pSirWifiScanResult->channel) )
2789 {
2790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2791 goto fail;
2792 }
2793 if (nla_put_s32(skb,
2794 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2795 pSirWifiScanResult->rssi) )
2796 {
2797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2798 goto fail;
2799 }
2800 if (nla_put_u32(skb,
2801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2802 pSirWifiScanResult->rtt) )
2803 {
2804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2805 goto fail;
2806 }
2807 if (nla_put_u32(skb,
2808 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2809 pSirWifiScanResult->rtt_sd))
2810 {
2811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2812 goto fail;
2813 }
2814 if (nla_put_u32(skb,
2815 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2816 pSirWifiScanResult->beaconPeriod))
2817 {
2818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2819 goto fail;
2820 }
2821 if (nla_put_u32(skb,
2822 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2823 pSirWifiScanResult->capability))
2824 {
2825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2826 goto fail;
2827 }
2828 if (nla_put_u32(skb,
2829 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2830 ieLength))
2831 {
2832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2833 goto fail;
2834 }
2835
2836 if (ieLength)
2837 if (nla_put(skb,
2838 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2839 ieLength, ie)) {
2840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2841 goto fail;
2842 }
2843
2844 nla_nest_end(skb, ap);
2845 }
2846 nla_nest_end(skb, aps);
2847 nla_nest_end(skb, nla_result);
2848 }
2849
2850 nla_nest_end(skb, nla_results);
2851
2852 cfg80211_vendor_cmd_reply(skb);
2853
2854 } while (totalResults > 0);
2855 }
2856
2857 if (!pData->moreData) {
2858 spin_lock(&hdd_context_lock);
2859 context->response_status = 0;
2860 complete(&context->response_event);
2861 spin_unlock(&hdd_context_lock);
2862 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302863
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302864 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302865 return;
2866fail:
2867 kfree_skb(skb);
2868 return;
2869}
2870
2871static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2872 void *pMsg)
2873{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302874 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302875 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2876 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302877 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302878
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302879 ENTER();
2880
2881 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302882 hddLog(LOGE,
2883 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302884 return;
2885 }
2886 if (!pMsg)
2887 {
2888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302889 return;
2890 }
2891
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302892 if (pData->bss_found)
2893 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2894 else
2895 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2896
Dino Mycle6fb96c12014-06-10 11:52:40 +05302897 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302898#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2899 NULL,
2900#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302901 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302902 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302903
2904 if (!skb) {
2905 hddLog(VOS_TRACE_LEVEL_ERROR,
2906 FL("cfg80211_vendor_event_alloc failed"));
2907 return;
2908 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302909
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302910 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2911 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2912 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2913 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2914
2915 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302916 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2917 "Ssid (%s) "
2918 "Bssid (" MAC_ADDRESS_STR ") "
2919 "Channel (%u) "
2920 "Rssi (%d) "
2921 "RTT (%u) "
2922 "RTT_SD (%u) ",
2923 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302924 pData->bssHotlist[i].ts,
2925 pData->bssHotlist[i].ssid,
2926 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2927 pData->bssHotlist[i].channel,
2928 pData->bssHotlist[i].rssi,
2929 pData->bssHotlist[i].rtt,
2930 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302931 }
2932
2933 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2934 pData->requestId) ||
2935 nla_put_u32(skb,
2936 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302937 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2939 goto fail;
2940 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302941 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302942 struct nlattr *aps;
2943
2944 aps = nla_nest_start(skb,
2945 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2946 if (!aps)
2947 goto fail;
2948
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302949 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302950 struct nlattr *ap;
2951
2952 ap = nla_nest_start(skb, i + 1);
2953 if (!ap)
2954 goto fail;
2955
2956 if (nla_put_u64(skb,
2957 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302958 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302959 nla_put(skb,
2960 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302961 sizeof(pData->bssHotlist[i].ssid),
2962 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302963 nla_put(skb,
2964 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302965 sizeof(pData->bssHotlist[i].bssid),
2966 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302967 nla_put_u32(skb,
2968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302969 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302970 nla_put_s32(skb,
2971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302972 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302973 nla_put_u32(skb,
2974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302975 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302976 nla_put_u32(skb,
2977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302978 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302979 goto fail;
2980
2981 nla_nest_end(skb, ap);
2982 }
2983 nla_nest_end(skb, aps);
2984
2985 if (nla_put_u8(skb,
2986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2987 pData->moreData))
2988 goto fail;
2989 }
2990
2991 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302992 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302993 return;
2994
2995fail:
2996 kfree_skb(skb);
2997 return;
2998
2999}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303000
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303001/**
3002 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
3003 * Handle an SSID hotlist match event
3004 * @ctx: HDD context registered with SME
3005 * @event: The SSID hotlist match event
3006 *
3007 * This function will take an SSID match event that was generated by
3008 * firmware and will convert it into a cfg80211 vendor event which is
3009 * sent to userspace.
3010 *
3011 * Return: none
3012 */
3013static void
3014wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
3015 void *pMsg)
3016{
3017 hdd_context_t *hdd_ctx = ctx;
3018 struct sk_buff *skb;
3019 tANI_U32 i, index;
3020 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3021
3022 ENTER();
3023
3024 if (wlan_hdd_validate_context(hdd_ctx)) {
3025 hddLog(LOGE,
3026 FL("HDD context is not valid or response"));
3027 return;
3028 }
3029 if (!pMsg)
3030 {
3031 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3032 return;
3033 }
3034
3035 if (pData->ssid_found) {
3036 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3037 hddLog(LOG1, "SSID hotlist found");
3038 } else {
3039 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3040 hddLog(LOG1, "SSID hotlist lost");
3041 }
3042
3043 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3044#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3045 NULL,
3046#endif
3047 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3048 index, GFP_KERNEL);
3049
3050 if (!skb) {
3051 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3052 return;
3053 }
3054 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3055 pData->requestId, pData->numHotlistSsid, pData->moreData);
3056
3057 for (i = 0; i < pData->numHotlistSsid; i++) {
3058 hddLog(LOG1, "[i=%d] Timestamp %llu "
3059 "Ssid: %s "
3060 "Bssid (" MAC_ADDRESS_STR ") "
3061 "Channel %u "
3062 "Rssi %d "
3063 "RTT %u "
3064 "RTT_SD %u",
3065 i,
3066 pData->ssidHotlist[i].ts,
3067 pData->ssidHotlist[i].ssid,
3068 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3069 pData->ssidHotlist[i].channel,
3070 pData->ssidHotlist[i].rssi,
3071 pData->ssidHotlist[i].rtt,
3072 pData->ssidHotlist[i].rtt_sd);
3073 }
3074
3075 if (nla_put_u32(skb,
3076 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3077 pData->requestId) ||
3078 nla_put_u32(skb,
3079 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3080 pData->numHotlistSsid)) {
3081 hddLog(LOGE, FL("put fail"));
3082 goto fail;
3083 }
3084
3085 if (pData->numHotlistSsid) {
3086 struct nlattr *aps;
3087 aps = nla_nest_start(skb,
3088 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3089 if (!aps) {
3090 hddLog(LOGE, FL("nest fail"));
3091 goto fail;
3092 }
3093
3094 for (i = 0; i < pData->numHotlistSsid; i++) {
3095 struct nlattr *ap;
3096
3097 ap = nla_nest_start(skb, i);
3098 if (!ap) {
3099 hddLog(LOGE, FL("nest fail"));
3100 goto fail;
3101 }
3102
3103 if (nla_put_u64(skb,
3104 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3105 pData->ssidHotlist[i].ts) ||
3106 nla_put(skb,
3107 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3108 sizeof(pData->ssidHotlist[i].ssid),
3109 pData->ssidHotlist[i].ssid) ||
3110 nla_put(skb,
3111 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3112 sizeof(pData->ssidHotlist[i].bssid),
3113 pData->ssidHotlist[i].bssid) ||
3114 nla_put_u32(skb,
3115 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3116 pData->ssidHotlist[i].channel) ||
3117 nla_put_s32(skb,
3118 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3119 pData->ssidHotlist[i].rssi) ||
3120 nla_put_u32(skb,
3121 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3122 pData->ssidHotlist[i].rtt) ||
3123 nla_put_u32(skb,
3124 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3125 pData->ssidHotlist[i].rtt_sd)) {
3126 hddLog(LOGE, FL("put fail"));
3127 goto fail;
3128 }
3129 nla_nest_end(skb, ap);
3130 }
3131 nla_nest_end(skb, aps);
3132
3133 if (nla_put_u8(skb,
3134 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3135 pData->moreData)) {
3136 hddLog(LOGE, FL("put fail"));
3137 goto fail;
3138 }
3139 }
3140
3141 cfg80211_vendor_event(skb, GFP_KERNEL);
3142 return;
3143
3144fail:
3145 kfree_skb(skb);
3146 return;
3147
3148}
3149
3150
Dino Mycle6fb96c12014-06-10 11:52:40 +05303151static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3152 void *pMsg)
3153{
3154 struct sk_buff *skb;
3155 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3156 tpSirWifiFullScanResultEvent pData =
3157 (tpSirWifiFullScanResultEvent) (pMsg);
3158
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303159 ENTER();
3160
3161 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303162 hddLog(LOGE,
3163 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303164 return;
3165 }
3166 if (!pMsg)
3167 {
3168 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303169 return;
3170 }
3171
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303172 /*
3173 * If the full scan result including IE data exceeds NL 4K size
3174 * limitation, drop that beacon/probe rsp frame.
3175 */
3176 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3177 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3178 return;
3179 }
3180
Dino Mycle6fb96c12014-06-10 11:52:40 +05303181 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303182#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3183 NULL,
3184#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303185 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3186 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3187 GFP_KERNEL);
3188
3189 if (!skb) {
3190 hddLog(VOS_TRACE_LEVEL_ERROR,
3191 FL("cfg80211_vendor_event_alloc failed"));
3192 return;
3193 }
3194
Dino Mycle6fb96c12014-06-10 11:52:40 +05303195 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3196 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3197 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3198 "Ssid (%s)"
3199 "Bssid (" MAC_ADDRESS_STR ")"
3200 "Channel (%u)"
3201 "Rssi (%d)"
3202 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303203 "RTT_SD (%u)"
3204 "Bcn Period %d"
3205 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303206 pData->ap.ts,
3207 pData->ap.ssid,
3208 MAC_ADDR_ARRAY(pData->ap.bssid),
3209 pData->ap.channel,
3210 pData->ap.rssi,
3211 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303212 pData->ap.rtt_sd,
3213 pData->ap.beaconPeriod,
3214 pData->ap.capability);
3215
Dino Mycle6fb96c12014-06-10 11:52:40 +05303216 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3217 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3218 pData->requestId) ||
3219 nla_put_u64(skb,
3220 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3221 pData->ap.ts) ||
3222 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3223 sizeof(pData->ap.ssid),
3224 pData->ap.ssid) ||
3225 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3226 WNI_CFG_BSSID_LEN,
3227 pData->ap.bssid) ||
3228 nla_put_u32(skb,
3229 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3230 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303231 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303232 pData->ap.rssi) ||
3233 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3234 pData->ap.rtt) ||
3235 nla_put_u32(skb,
3236 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3237 pData->ap.rtt_sd) ||
3238 nla_put_u16(skb,
3239 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3240 pData->ap.beaconPeriod) ||
3241 nla_put_u16(skb,
3242 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3243 pData->ap.capability) ||
3244 nla_put_u32(skb,
3245 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303246 pData->ieLength) ||
3247 nla_put_u8(skb,
3248 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3249 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303250 {
3251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3252 goto nla_put_failure;
3253 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303254
3255 if (pData->ieLength) {
3256 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3257 pData->ieLength,
3258 pData->ie))
3259 {
3260 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3261 goto nla_put_failure;
3262 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303263 }
3264
3265 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303266 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303267 return;
3268
3269nla_put_failure:
3270 kfree_skb(skb);
3271 return;
3272}
3273
3274static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3275 void *pMsg)
3276{
3277 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3278 struct sk_buff *skb = NULL;
3279 tpSirEXTScanResultsAvailableIndParams pData =
3280 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3281
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303282 ENTER();
3283
3284 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303285 hddLog(LOGE,
3286 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303287 return;
3288 }
3289 if (!pMsg)
3290 {
3291 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303292 return;
3293 }
3294
3295 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303296#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3297 NULL,
3298#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303299 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3300 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3301 GFP_KERNEL);
3302
3303 if (!skb) {
3304 hddLog(VOS_TRACE_LEVEL_ERROR,
3305 FL("cfg80211_vendor_event_alloc failed"));
3306 return;
3307 }
3308
Dino Mycle6fb96c12014-06-10 11:52:40 +05303309 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3310 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3311 pData->numResultsAvailable);
3312 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3313 pData->requestId) ||
3314 nla_put_u32(skb,
3315 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3316 pData->numResultsAvailable)) {
3317 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3318 goto nla_put_failure;
3319 }
3320
3321 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303322 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303323 return;
3324
3325nla_put_failure:
3326 kfree_skb(skb);
3327 return;
3328}
3329
3330static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3331{
3332 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3333 struct sk_buff *skb = NULL;
3334 tpSirEXTScanProgressIndParams pData =
3335 (tpSirEXTScanProgressIndParams) pMsg;
3336
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303337 ENTER();
3338
3339 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303340 hddLog(LOGE,
3341 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303342 return;
3343 }
3344 if (!pMsg)
3345 {
3346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303347 return;
3348 }
3349
3350 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303351#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3352 NULL,
3353#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303354 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3355 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3356 GFP_KERNEL);
3357
3358 if (!skb) {
3359 hddLog(VOS_TRACE_LEVEL_ERROR,
3360 FL("cfg80211_vendor_event_alloc failed"));
3361 return;
3362 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303363 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303364 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3365 pData->extScanEventType);
3366 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3367 pData->status);
3368
3369 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3370 pData->extScanEventType) ||
3371 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303372 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3373 pData->requestId) ||
3374 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303375 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3376 pData->status)) {
3377 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3378 goto nla_put_failure;
3379 }
3380
3381 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303382 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303383 return;
3384
3385nla_put_failure:
3386 kfree_skb(skb);
3387 return;
3388}
3389
3390void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3391 void *pMsg)
3392{
3393 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3394
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303395 ENTER();
3396
Dino Mycle6fb96c12014-06-10 11:52:40 +05303397 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303398 return;
3399 }
3400
3401 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3402
3403
3404 switch(evType) {
3405 case SIR_HAL_EXTSCAN_START_RSP:
3406 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3407 break;
3408
3409 case SIR_HAL_EXTSCAN_STOP_RSP:
3410 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3411 break;
3412 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3413 /* There is no need to send this response to upper layer
3414 Just log the message */
3415 hddLog(VOS_TRACE_LEVEL_INFO,
3416 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3417 break;
3418 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3419 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3420 break;
3421
3422 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3423 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3424 break;
3425
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303426 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3427 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3428 break;
3429
3430 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3431 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3432 break;
3433
Dino Mycle6fb96c12014-06-10 11:52:40 +05303434 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303435 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303436 break;
3437 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3438 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3439 break;
3440 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3441 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3442 break;
3443 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3444 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3445 break;
3446 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3447 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3448 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303449 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3450 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3451 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303452 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3453 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3454 break;
3455 default:
3456 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3457 break;
3458 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303459 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460}
3461
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303462static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3463 struct wireless_dev *wdev,
3464 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303465{
Dino Myclee8843b32014-07-04 14:21:45 +05303466 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303467 struct net_device *dev = wdev->netdev;
3468 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3469 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3470 struct nlattr
3471 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3472 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303473 struct hdd_ext_scan_context *context;
3474 unsigned long rc;
3475 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303476
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303477 ENTER();
3478
Dino Mycle6fb96c12014-06-10 11:52:40 +05303479 status = wlan_hdd_validate_context(pHddCtx);
3480 if (0 != status)
3481 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303482 return -EINVAL;
3483 }
Dino Myclee8843b32014-07-04 14:21:45 +05303484 /* check the EXTScan Capability */
3485 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303486 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3487 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303488 {
3489 hddLog(VOS_TRACE_LEVEL_ERROR,
3490 FL("EXTScan not enabled/supported by Firmware"));
3491 return -EINVAL;
3492 }
3493
Dino Mycle6fb96c12014-06-10 11:52:40 +05303494 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3495 data, dataLen,
3496 wlan_hdd_extscan_config_policy)) {
3497 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3498 return -EINVAL;
3499 }
3500
3501 /* Parse and fetch request Id */
3502 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3503 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3504 return -EINVAL;
3505 }
3506
Dino Myclee8843b32014-07-04 14:21:45 +05303507 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303508 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303509 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303510
Dino Myclee8843b32014-07-04 14:21:45 +05303511 reqMsg.sessionId = pAdapter->sessionId;
3512 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303513
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303514 vos_spin_lock_acquire(&hdd_context_lock);
3515 context = &pHddCtx->ext_scan_context;
3516 context->request_id = reqMsg.requestId;
3517 INIT_COMPLETION(context->response_event);
3518 vos_spin_lock_release(&hdd_context_lock);
3519
Dino Myclee8843b32014-07-04 14:21:45 +05303520 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303521 if (!HAL_STATUS_SUCCESS(status)) {
3522 hddLog(VOS_TRACE_LEVEL_ERROR,
3523 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303524 return -EINVAL;
3525 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303526
3527 rc = wait_for_completion_timeout(&context->response_event,
3528 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3529 if (!rc) {
3530 hddLog(LOGE, FL("Target response timed out"));
3531 return -ETIMEDOUT;
3532 }
3533
3534 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3535 if (ret)
3536 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3537
3538 return ret;
3539
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303540 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303541 return 0;
3542}
3543
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303544static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3545 struct wireless_dev *wdev,
3546 const void *data, int dataLen)
3547{
3548 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303549
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303550 vos_ssr_protect(__func__);
3551 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3552 vos_ssr_unprotect(__func__);
3553
3554 return ret;
3555}
3556
3557static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3558 struct wireless_dev *wdev,
3559 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303560{
Dino Myclee8843b32014-07-04 14:21:45 +05303561 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303562 struct net_device *dev = wdev->netdev;
3563 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3564 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3565 struct nlattr
3566 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3567 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303568 struct hdd_ext_scan_context *context;
3569 unsigned long rc;
3570 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303571
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303572 ENTER();
3573
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303574 if (VOS_FTM_MODE == hdd_get_conparam()) {
3575 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3576 return -EINVAL;
3577 }
3578
Dino Mycle6fb96c12014-06-10 11:52:40 +05303579 status = wlan_hdd_validate_context(pHddCtx);
3580 if (0 != status)
3581 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303582 return -EINVAL;
3583 }
Dino Myclee8843b32014-07-04 14:21:45 +05303584 /* check the EXTScan Capability */
3585 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303586 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3587 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303588 {
3589 hddLog(VOS_TRACE_LEVEL_ERROR,
3590 FL("EXTScan not enabled/supported by Firmware"));
3591 return -EINVAL;
3592 }
3593
Dino Mycle6fb96c12014-06-10 11:52:40 +05303594 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3595 data, dataLen,
3596 wlan_hdd_extscan_config_policy)) {
3597 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3598 return -EINVAL;
3599 }
3600 /* Parse and fetch request Id */
3601 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3602 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3603 return -EINVAL;
3604 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303605
Dino Myclee8843b32014-07-04 14:21:45 +05303606 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303607 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3608
Dino Myclee8843b32014-07-04 14:21:45 +05303609 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303610
Dino Myclee8843b32014-07-04 14:21:45 +05303611 reqMsg.sessionId = pAdapter->sessionId;
3612 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303613
3614 /* Parse and fetch flush parameter */
3615 if (!tb
3616 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3617 {
3618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3619 goto failed;
3620 }
Dino Myclee8843b32014-07-04 14:21:45 +05303621 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303622 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3623
Dino Myclee8843b32014-07-04 14:21:45 +05303624 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303626 spin_lock(&hdd_context_lock);
3627 context = &pHddCtx->ext_scan_context;
3628 context->request_id = reqMsg.requestId;
3629 context->ignore_cached_results = false;
3630 INIT_COMPLETION(context->response_event);
3631 spin_unlock(&hdd_context_lock);
3632
Dino Myclee8843b32014-07-04 14:21:45 +05303633 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303634 if (!HAL_STATUS_SUCCESS(status)) {
3635 hddLog(VOS_TRACE_LEVEL_ERROR,
3636 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303637 return -EINVAL;
3638 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303639
3640 rc = wait_for_completion_timeout(&context->response_event,
3641 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3642 if (!rc) {
3643 hddLog(LOGE, FL("Target response timed out"));
3644 retval = -ETIMEDOUT;
3645 spin_lock(&hdd_context_lock);
3646 context->ignore_cached_results = true;
3647 spin_unlock(&hdd_context_lock);
3648 } else {
3649 spin_lock(&hdd_context_lock);
3650 retval = context->response_status;
3651 spin_unlock(&hdd_context_lock);
3652 }
3653
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303654 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303655 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303656
3657failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303658 return -EINVAL;
3659}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303660static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3661 struct wireless_dev *wdev,
3662 const void *data, int dataLen)
3663{
3664 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303665
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303666 vos_ssr_protect(__func__);
3667 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3668 vos_ssr_unprotect(__func__);
3669
3670 return ret;
3671}
3672
3673static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303674 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303675 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303676{
3677 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3678 struct net_device *dev = wdev->netdev;
3679 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3680 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3681 struct nlattr
3682 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3683 struct nlattr
3684 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3685 struct nlattr *apTh;
3686 eHalStatus status;
3687 tANI_U8 i = 0;
3688 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303689 struct hdd_ext_scan_context *context;
3690 tANI_U32 request_id;
3691 unsigned long rc;
3692 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303693
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303694 ENTER();
3695
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303696 if (VOS_FTM_MODE == hdd_get_conparam()) {
3697 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3698 return -EINVAL;
3699 }
3700
Dino Mycle6fb96c12014-06-10 11:52:40 +05303701 status = wlan_hdd_validate_context(pHddCtx);
3702 if (0 != status)
3703 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303704 return -EINVAL;
3705 }
Dino Myclee8843b32014-07-04 14:21:45 +05303706 /* check the EXTScan Capability */
3707 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303708 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3709 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303710 {
3711 hddLog(VOS_TRACE_LEVEL_ERROR,
3712 FL("EXTScan not enabled/supported by Firmware"));
3713 return -EINVAL;
3714 }
3715
Dino Mycle6fb96c12014-06-10 11:52:40 +05303716 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3717 data, dataLen,
3718 wlan_hdd_extscan_config_policy)) {
3719 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3720 return -EINVAL;
3721 }
3722
3723 /* Parse and fetch request Id */
3724 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3726 return -EINVAL;
3727 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303728 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3729 vos_mem_malloc(sizeof(*pReqMsg));
3730 if (!pReqMsg) {
3731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3732 return -ENOMEM;
3733 }
3734
Dino Myclee8843b32014-07-04 14:21:45 +05303735
Dino Mycle6fb96c12014-06-10 11:52:40 +05303736 pReqMsg->requestId = nla_get_u32(
3737 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3738 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3739
3740 /* Parse and fetch number of APs */
3741 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3742 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3743 goto fail;
3744 }
3745
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303746 /* Parse and fetch lost ap sample size */
3747 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3748 hddLog(LOGE, FL("attr lost ap sample size failed"));
3749 goto fail;
3750 }
3751
3752 pReqMsg->lostBssidSampleSize = nla_get_u32(
3753 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3754 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3755
Dino Mycle6fb96c12014-06-10 11:52:40 +05303756 pReqMsg->sessionId = pAdapter->sessionId;
3757 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3758
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303759 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303760 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303761 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303762
3763 nla_for_each_nested(apTh,
3764 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3765 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3766 nla_data(apTh), nla_len(apTh),
3767 NULL)) {
3768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3769 goto fail;
3770 }
3771
3772 /* Parse and fetch MAC address */
3773 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3775 goto fail;
3776 }
3777 memcpy(pReqMsg->ap[i].bssid, nla_data(
3778 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3779 sizeof(tSirMacAddr));
3780 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3781
3782 /* Parse and fetch low RSSI */
3783 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3785 goto fail;
3786 }
3787 pReqMsg->ap[i].low = nla_get_s32(
3788 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3789 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3790
3791 /* Parse and fetch high RSSI */
3792 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3794 goto fail;
3795 }
3796 pReqMsg->ap[i].high = nla_get_s32(
3797 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3798 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3799 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303800 i++;
3801 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303802
3803 context = &pHddCtx->ext_scan_context;
3804 spin_lock(&hdd_context_lock);
3805 INIT_COMPLETION(context->response_event);
3806 context->request_id = request_id = pReqMsg->requestId;
3807 spin_unlock(&hdd_context_lock);
3808
Dino Mycle6fb96c12014-06-10 11:52:40 +05303809 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3810 if (!HAL_STATUS_SUCCESS(status)) {
3811 hddLog(VOS_TRACE_LEVEL_ERROR,
3812 FL("sme_SetBssHotlist failed(err=%d)"), status);
3813 vos_mem_free(pReqMsg);
3814 return -EINVAL;
3815 }
3816
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303817 /* request was sent -- wait for the response */
3818 rc = wait_for_completion_timeout(&context->response_event,
3819 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3820
3821 if (!rc) {
3822 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3823 retval = -ETIMEDOUT;
3824 } else {
3825 spin_lock(&hdd_context_lock);
3826 if (context->request_id == request_id)
3827 retval = context->response_status;
3828 else
3829 retval = -EINVAL;
3830 spin_unlock(&hdd_context_lock);
3831 }
3832
Dino Myclee8843b32014-07-04 14:21:45 +05303833 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303834 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303835 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303836
3837fail:
3838 vos_mem_free(pReqMsg);
3839 return -EINVAL;
3840}
3841
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303842static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3843 struct wireless_dev *wdev,
3844 const void *data, int dataLen)
3845{
3846 int ret = 0;
3847
3848 vos_ssr_protect(__func__);
3849 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3850 dataLen);
3851 vos_ssr_unprotect(__func__);
3852
3853 return ret;
3854}
3855
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303856/*
3857 * define short names for the global vendor params
3858 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3859 */
3860#define PARAM_MAX \
3861QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3862#define PARAM_REQUEST_ID \
3863QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3864#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3865QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3866#define PARAMS_NUM_SSID \
3867QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3868#define THRESHOLD_PARAM \
3869QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3870#define PARAM_SSID \
3871QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3872#define PARAM_BAND \
3873QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3874#define PARAM_RSSI_LOW \
3875QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3876#define PARAM_RSSI_HIGH \
3877QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3878
3879/**
3880 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3881 * @wiphy: Pointer to wireless phy
3882 * @wdev: Pointer to wireless device
3883 * @data: Pointer to data
3884 * @data_len: Data length
3885 *
3886 * Return: 0 on success, negative errno on failure
3887 */
3888static int
3889__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3890 struct wireless_dev *wdev,
3891 const void *data,
3892 int data_len)
3893{
3894 tSirEXTScanSetSsidHotListReqParams *request;
3895 struct net_device *dev = wdev->netdev;
3896 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3897 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3898 struct nlattr *tb[PARAM_MAX + 1];
3899 struct nlattr *tb2[PARAM_MAX + 1];
3900 struct nlattr *ssids;
3901 struct hdd_ext_scan_context *context;
3902 uint32_t request_id;
3903 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3904 int ssid_len;
3905 eHalStatus status;
3906 int i, rem, retval;
3907 unsigned long rc;
3908
3909 ENTER();
3910
3911 if (VOS_FTM_MODE == hdd_get_conparam()) {
3912 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3913 return -EINVAL;
3914 }
3915
3916 retval = wlan_hdd_validate_context(hdd_ctx);
3917 if (0 != retval) {
3918 hddLog(LOGE, FL("HDD context is not valid"));
3919 return -EINVAL;
3920 }
3921
3922 /* check the EXTScan Capability */
3923 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303924 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3925 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303926 {
3927 hddLog(VOS_TRACE_LEVEL_ERROR,
3928 FL("EXTScan not enabled/supported by Firmware"));
3929 return -EINVAL;
3930 }
3931
3932 if (nla_parse(tb, PARAM_MAX,
3933 data, data_len,
3934 wlan_hdd_extscan_config_policy)) {
3935 hddLog(LOGE, FL("Invalid ATTR"));
3936 return -EINVAL;
3937 }
3938
3939 request = vos_mem_malloc(sizeof(*request));
3940 if (!request) {
3941 hddLog(LOGE, FL("vos_mem_malloc failed"));
3942 return -ENOMEM;
3943 }
3944
3945 /* Parse and fetch request Id */
3946 if (!tb[PARAM_REQUEST_ID]) {
3947 hddLog(LOGE, FL("attr request id failed"));
3948 goto fail;
3949 }
3950
3951 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3952 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3953
3954 /* Parse and fetch lost SSID sample size */
3955 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3956 hddLog(LOGE, FL("attr number of Ssid failed"));
3957 goto fail;
3958 }
3959 request->lost_ssid_sample_size =
3960 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3961 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3962 request->lost_ssid_sample_size);
3963
3964 /* Parse and fetch number of hotlist SSID */
3965 if (!tb[PARAMS_NUM_SSID]) {
3966 hddLog(LOGE, FL("attr number of Ssid failed"));
3967 goto fail;
3968 }
3969 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3970 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3971
3972 request->session_id = adapter->sessionId;
3973 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3974
3975 i = 0;
3976 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3977 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3978 hddLog(LOGE,
3979 FL("Too Many SSIDs, %d exceeds %d"),
3980 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3981 break;
3982 }
3983 if (nla_parse(tb2, PARAM_MAX,
3984 nla_data(ssids), nla_len(ssids),
3985 wlan_hdd_extscan_config_policy)) {
3986 hddLog(LOGE, FL("nla_parse failed"));
3987 goto fail;
3988 }
3989
3990 /* Parse and fetch SSID */
3991 if (!tb2[PARAM_SSID]) {
3992 hddLog(LOGE, FL("attr ssid failed"));
3993 goto fail;
3994 }
3995 nla_memcpy(ssid_string,
3996 tb2[PARAM_SSID],
3997 sizeof(ssid_string));
3998 hddLog(LOG1, FL("SSID %s"),
3999 ssid_string);
4000 ssid_len = strlen(ssid_string);
4001 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
4002 request->ssid[i].ssid.length = ssid_len;
4003 request->ssid[i].ssid.ssId[ssid_len] = '\0';
4004 hddLog(LOG1, FL("After copying SSID %s"),
4005 request->ssid[i].ssid.ssId);
4006 hddLog(LOG1, FL("After copying length: %d"),
4007 ssid_len);
4008
4009 /* Parse and fetch low RSSI */
4010 if (!tb2[PARAM_BAND]) {
4011 hddLog(LOGE, FL("attr band failed"));
4012 goto fail;
4013 }
4014 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
4015 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
4016
4017 /* Parse and fetch low RSSI */
4018 if (!tb2[PARAM_RSSI_LOW]) {
4019 hddLog(LOGE, FL("attr low RSSI failed"));
4020 goto fail;
4021 }
4022 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4023 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4024
4025 /* Parse and fetch high RSSI */
4026 if (!tb2[PARAM_RSSI_HIGH]) {
4027 hddLog(LOGE, FL("attr high RSSI failed"));
4028 goto fail;
4029 }
4030 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4031 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4032 i++;
4033 }
4034
4035 context = &hdd_ctx->ext_scan_context;
4036 spin_lock(&hdd_context_lock);
4037 INIT_COMPLETION(context->response_event);
4038 context->request_id = request_id = request->request_id;
4039 spin_unlock(&hdd_context_lock);
4040
4041 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4042 if (!HAL_STATUS_SUCCESS(status)) {
4043 hddLog(LOGE,
4044 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4045 goto fail;
4046 }
4047
4048 vos_mem_free(request);
4049
4050 /* request was sent -- wait for the response */
4051 rc = wait_for_completion_timeout(&context->response_event,
4052 msecs_to_jiffies
4053 (WLAN_WAIT_TIME_EXTSCAN));
4054 if (!rc) {
4055 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4056 retval = -ETIMEDOUT;
4057 } else {
4058 spin_lock(&hdd_context_lock);
4059 if (context->request_id == request_id)
4060 retval = context->response_status;
4061 else
4062 retval = -EINVAL;
4063 spin_unlock(&hdd_context_lock);
4064 }
4065
4066 return retval;
4067
4068fail:
4069 vos_mem_free(request);
4070 return -EINVAL;
4071}
4072
4073/*
4074 * done with short names for the global vendor params
4075 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4076 */
4077#undef PARAM_MAX
4078#undef PARAM_REQUEST_ID
4079#undef PARAMS_NUM_SSID
4080#undef THRESHOLD_PARAM
4081#undef PARAM_SSID
4082#undef PARAM_BAND
4083#undef PARAM_RSSI_LOW
4084#undef PARAM_RSSI_HIGH
4085
4086static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4087 struct wireless_dev *wdev,
4088 const void *data, int dataLen)
4089{
4090 int ret = 0;
4091
4092 vos_ssr_protect(__func__);
4093 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4094 dataLen);
4095 vos_ssr_unprotect(__func__);
4096
4097 return ret;
4098}
4099
4100static int
4101__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4102 struct wireless_dev *wdev,
4103 const void *data,
4104 int data_len)
4105{
4106 tSirEXTScanResetSsidHotlistReqParams request;
4107 struct net_device *dev = wdev->netdev;
4108 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4109 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4110 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4111 struct hdd_ext_scan_context *context;
4112 uint32_t request_id;
4113 eHalStatus status;
4114 int retval;
4115 unsigned long rc;
4116
4117 ENTER();
4118
4119 if (VOS_FTM_MODE == hdd_get_conparam()) {
4120 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4121 return -EINVAL;
4122 }
4123
4124 retval = wlan_hdd_validate_context(hdd_ctx);
4125 if (0 != retval) {
4126 hddLog(LOGE, FL("HDD context is not valid"));
4127 return -EINVAL;
4128 }
4129
4130 /* check the EXTScan Capability */
4131 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304132 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4133 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304134 {
4135 hddLog(LOGE,
4136 FL("EXTScan not enabled/supported by Firmware"));
4137 return -EINVAL;
4138 }
4139
4140 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4141 data, data_len,
4142 wlan_hdd_extscan_config_policy)) {
4143 hddLog(LOGE, FL("Invalid ATTR"));
4144 return -EINVAL;
4145 }
4146
4147 /* Parse and fetch request Id */
4148 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4149 hddLog(LOGE, FL("attr request id failed"));
4150 return -EINVAL;
4151 }
4152
4153 request.requestId = nla_get_u32(
4154 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4155 request.sessionId = adapter->sessionId;
4156 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4157 request.sessionId);
4158
4159 context = &hdd_ctx->ext_scan_context;
4160 spin_lock(&hdd_context_lock);
4161 INIT_COMPLETION(context->response_event);
4162 context->request_id = request_id = request.requestId;
4163 spin_unlock(&hdd_context_lock);
4164
4165 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4166 if (!HAL_STATUS_SUCCESS(status)) {
4167 hddLog(LOGE,
4168 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4169 return -EINVAL;
4170 }
4171
4172 /* request was sent -- wait for the response */
4173 rc = wait_for_completion_timeout(&context->response_event,
4174 msecs_to_jiffies
4175 (WLAN_WAIT_TIME_EXTSCAN));
4176 if (!rc) {
4177 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4178 retval = -ETIMEDOUT;
4179 } else {
4180 spin_lock(&hdd_context_lock);
4181 if (context->request_id == request_id)
4182 retval = context->response_status;
4183 else
4184 retval = -EINVAL;
4185 spin_unlock(&hdd_context_lock);
4186 }
4187
4188 return retval;
4189}
4190
4191static int
4192wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4193 struct wireless_dev *wdev,
4194 const void *data,
4195 int data_len)
4196{
4197 int ret;
4198
4199 vos_ssr_protect(__func__);
4200 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4201 data, data_len);
4202 vos_ssr_unprotect(__func__);
4203
4204 return ret;
4205}
4206
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304207static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304208 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304209 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304210{
4211 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4212 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4213 tANI_U8 numChannels = 0;
4214 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304215 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304216 tWifiBand wifiBand;
4217 eHalStatus status;
4218 struct sk_buff *replySkb;
4219 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304220 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304221
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304222 ENTER();
4223
Dino Mycle6fb96c12014-06-10 11:52:40 +05304224 status = wlan_hdd_validate_context(pHddCtx);
4225 if (0 != status)
4226 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304227 return -EINVAL;
4228 }
Dino Myclee8843b32014-07-04 14:21:45 +05304229
Dino Mycle6fb96c12014-06-10 11:52:40 +05304230 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4231 data, dataLen,
4232 wlan_hdd_extscan_config_policy)) {
4233 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4234 return -EINVAL;
4235 }
4236
4237 /* Parse and fetch request Id */
4238 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4240 return -EINVAL;
4241 }
4242 requestId = nla_get_u32(
4243 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4244 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4245
4246 /* Parse and fetch wifi band */
4247 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4248 {
4249 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4250 return -EINVAL;
4251 }
4252 wifiBand = nla_get_u32(
4253 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4254 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4255
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304256 /* Parse and fetch max channels */
4257 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4258 {
4259 hddLog(LOGE, FL("attr max channels failed"));
4260 return -EINVAL;
4261 }
4262 maxChannels = nla_get_u32(
4263 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4264 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4265
Dino Mycle6fb96c12014-06-10 11:52:40 +05304266 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4267 wifiBand, ChannelList,
4268 &numChannels);
4269 if (eHAL_STATUS_SUCCESS != status) {
4270 hddLog(VOS_TRACE_LEVEL_ERROR,
4271 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4272 return -EINVAL;
4273 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304274
4275 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304276 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304277
Dino Mycle6fb96c12014-06-10 11:52:40 +05304278 for (i = 0; i < numChannels; i++)
4279 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4280
4281 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4282 sizeof(u32) * numChannels +
4283 NLMSG_HDRLEN);
4284
4285 if (!replySkb) {
4286 hddLog(VOS_TRACE_LEVEL_ERROR,
4287 FL("valid channels: buffer alloc fail"));
4288 return -EINVAL;
4289 }
4290 if (nla_put_u32(replySkb,
4291 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4292 numChannels) ||
4293 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4294 sizeof(u32) * numChannels, ChannelList)) {
4295
4296 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4297 kfree_skb(replySkb);
4298 return -EINVAL;
4299 }
4300
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304301 ret = cfg80211_vendor_cmd_reply(replySkb);
4302
4303 EXIT();
4304 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304305}
4306
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304307static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4308 struct wireless_dev *wdev,
4309 const void *data, int dataLen)
4310{
4311 int ret = 0;
4312
4313 vos_ssr_protect(__func__);
4314 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4315 dataLen);
4316 vos_ssr_unprotect(__func__);
4317
4318 return ret;
4319}
4320
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304321static int hdd_extscan_start_fill_bucket_channel_spec(
4322 hdd_context_t *pHddCtx,
4323 tpSirEXTScanStartReqParams pReqMsg,
4324 struct nlattr **tb)
4325{
4326 struct nlattr *bucket[
4327 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4328 struct nlattr *channel[
4329 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4330 struct nlattr *buckets;
4331 struct nlattr *channels;
4332 int rem1, rem2;
4333 eHalStatus status;
4334 tANI_U8 bktIndex, j, numChannels;
4335 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4336 tANI_U32 passive_max_chn_time, active_max_chn_time;
4337
4338 bktIndex = 0;
4339
4340 nla_for_each_nested(buckets,
4341 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4342 if (nla_parse(bucket,
4343 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4344 nla_data(buckets), nla_len(buckets), NULL)) {
4345 hddLog(LOGE, FL("nla_parse failed"));
4346 return -EINVAL;
4347 }
4348
4349 /* Parse and fetch bucket spec */
4350 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4351 hddLog(LOGE, FL("attr bucket index failed"));
4352 return -EINVAL;
4353 }
4354 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4355 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4356 hddLog(LOG1, FL("Bucket spec Index %d"),
4357 pReqMsg->buckets[bktIndex].bucket);
4358
4359 /* Parse and fetch wifi band */
4360 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4361 hddLog(LOGE, FL("attr wifi band failed"));
4362 return -EINVAL;
4363 }
4364 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4365 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4366 hddLog(LOG1, FL("Wifi band %d"),
4367 pReqMsg->buckets[bktIndex].band);
4368
4369 /* Parse and fetch period */
4370 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4371 hddLog(LOGE, FL("attr period failed"));
4372 return -EINVAL;
4373 }
4374 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4375 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4376 hddLog(LOG1, FL("period %d"),
4377 pReqMsg->buckets[bktIndex].period);
4378
4379 /* Parse and fetch report events */
4380 if (!bucket[
4381 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4382 hddLog(LOGE, FL("attr report events failed"));
4383 return -EINVAL;
4384 }
4385 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4386 bucket[
4387 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4388 hddLog(LOG1, FL("report events %d"),
4389 pReqMsg->buckets[bktIndex].reportEvents);
4390
4391 /* Parse and fetch max period */
4392 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4393 hddLog(LOGE, FL("attr max period failed"));
4394 return -EINVAL;
4395 }
4396 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4397 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4398 hddLog(LOG1, FL("max period %u"),
4399 pReqMsg->buckets[bktIndex].max_period);
4400
4401 /* Parse and fetch exponent */
4402 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4403 hddLog(LOGE, FL("attr exponent failed"));
4404 return -EINVAL;
4405 }
4406 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4407 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4408 hddLog(LOG1, FL("exponent %u"),
4409 pReqMsg->buckets[bktIndex].exponent);
4410
4411 /* Parse and fetch step count */
4412 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4413 hddLog(LOGE, FL("attr step count failed"));
4414 return -EINVAL;
4415 }
4416 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4417 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4418 hddLog(LOG1, FL("Step count %u"),
4419 pReqMsg->buckets[bktIndex].step_count);
4420
4421 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4422 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4423
4424 /* Framework shall pass the channel list if the input WiFi band is
4425 * WIFI_BAND_UNSPECIFIED.
4426 * If the input WiFi band is specified (any value other than
4427 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4428 */
4429 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4430 numChannels = 0;
4431 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4432 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4433 pReqMsg->buckets[bktIndex].band,
4434 chanList, &numChannels);
4435 if (!HAL_STATUS_SUCCESS(status)) {
4436 hddLog(LOGE,
4437 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4438 status);
4439 return -EINVAL;
4440 }
4441
4442 pReqMsg->buckets[bktIndex].numChannels =
4443 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4444 hddLog(LOG1, FL("Num channels %d"),
4445 pReqMsg->buckets[bktIndex].numChannels);
4446
4447 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4448 j++) {
4449 pReqMsg->buckets[bktIndex].channels[j].channel =
4450 chanList[j];
4451 pReqMsg->buckets[bktIndex].channels[j].
4452 chnlClass = 0;
4453 if (CSR_IS_CHANNEL_DFS(
4454 vos_freq_to_chan(chanList[j]))) {
4455 pReqMsg->buckets[bktIndex].channels[j].
4456 passive = 1;
4457 pReqMsg->buckets[bktIndex].channels[j].
4458 dwellTimeMs = passive_max_chn_time;
4459 } else {
4460 pReqMsg->buckets[bktIndex].channels[j].
4461 passive = 0;
4462 pReqMsg->buckets[bktIndex].channels[j].
4463 dwellTimeMs = active_max_chn_time;
4464 }
4465
4466 hddLog(LOG1,
4467 "Channel %u Passive %u Dwell time %u ms",
4468 pReqMsg->buckets[bktIndex].channels[j].channel,
4469 pReqMsg->buckets[bktIndex].channels[j].passive,
4470 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4471 }
4472
4473 bktIndex++;
4474 continue;
4475 }
4476
4477 /* Parse and fetch number of channels */
4478 if (!bucket[
4479 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4480 hddLog(LOGE, FL("attr num channels failed"));
4481 return -EINVAL;
4482 }
4483
4484 pReqMsg->buckets[bktIndex].numChannels =
4485 nla_get_u32(bucket[
4486 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4487 hddLog(LOG1, FL("num channels %d"),
4488 pReqMsg->buckets[bktIndex].numChannels);
4489
4490 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4491 hddLog(LOGE, FL("attr channel spec failed"));
4492 return -EINVAL;
4493 }
4494
4495 j = 0;
4496 nla_for_each_nested(channels,
4497 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4498 if (nla_parse(channel,
4499 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4500 nla_data(channels), nla_len(channels),
4501 wlan_hdd_extscan_config_policy)) {
4502 hddLog(LOGE, FL("nla_parse failed"));
4503 return -EINVAL;
4504 }
4505
4506 /* Parse and fetch channel */
4507 if (!channel[
4508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4509 hddLog(LOGE, FL("attr channel failed"));
4510 return -EINVAL;
4511 }
4512 pReqMsg->buckets[bktIndex].channels[j].channel =
4513 nla_get_u32(channel[
4514 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4515 hddLog(LOG1, FL("channel %u"),
4516 pReqMsg->buckets[bktIndex].channels[j].channel);
4517
4518 /* Parse and fetch dwell time */
4519 if (!channel[
4520 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4521 hddLog(LOGE, FL("attr dwelltime failed"));
4522 return -EINVAL;
4523 }
4524 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4525 nla_get_u32(channel[
4526 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4527
4528 hddLog(LOG1, FL("Dwell time (%u ms)"),
4529 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4530
4531
4532 /* Parse and fetch channel spec passive */
4533 if (!channel[
4534 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4535 hddLog(LOGE,
4536 FL("attr channel spec passive failed"));
4537 return -EINVAL;
4538 }
4539 pReqMsg->buckets[bktIndex].channels[j].passive =
4540 nla_get_u8(channel[
4541 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4542 hddLog(LOG1, FL("Chnl spec passive %u"),
4543 pReqMsg->buckets[bktIndex].channels[j].passive);
4544
4545 j++;
4546 }
4547
4548 bktIndex++;
4549 }
4550
4551 return 0;
4552}
4553
4554
4555/*
4556 * define short names for the global vendor params
4557 * used by wlan_hdd_cfg80211_extscan_start()
4558 */
4559#define PARAM_MAX \
4560QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4561#define PARAM_REQUEST_ID \
4562QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4563#define PARAM_BASE_PERIOD \
4564QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4565#define PARAM_MAX_AP_PER_SCAN \
4566QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4567#define PARAM_RPT_THRHLD_PERCENT \
4568QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4569#define PARAM_RPT_THRHLD_NUM_SCANS \
4570QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4571#define PARAM_NUM_BUCKETS \
4572QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4573
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304574static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304575 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304576 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304577{
Dino Myclee8843b32014-07-04 14:21:45 +05304578 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304579 struct net_device *dev = wdev->netdev;
4580 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4581 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4582 struct nlattr *tb[PARAM_MAX + 1];
4583 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304584 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304585 tANI_U32 request_id;
4586 struct hdd_ext_scan_context *context;
4587 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304588
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304589 ENTER();
4590
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304591 if (VOS_FTM_MODE == hdd_get_conparam()) {
4592 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4593 return -EINVAL;
4594 }
4595
Dino Mycle6fb96c12014-06-10 11:52:40 +05304596 status = wlan_hdd_validate_context(pHddCtx);
4597 if (0 != status)
4598 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304599 return -EINVAL;
4600 }
Dino Myclee8843b32014-07-04 14:21:45 +05304601 /* check the EXTScan Capability */
4602 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304603 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4604 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304605 {
4606 hddLog(VOS_TRACE_LEVEL_ERROR,
4607 FL("EXTScan not enabled/supported by Firmware"));
4608 return -EINVAL;
4609 }
4610
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304611 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304612 data, dataLen,
4613 wlan_hdd_extscan_config_policy)) {
4614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4615 return -EINVAL;
4616 }
4617
4618 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304619 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304620 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4621 return -EINVAL;
4622 }
4623
Dino Myclee8843b32014-07-04 14:21:45 +05304624 pReqMsg = (tpSirEXTScanStartReqParams)
4625 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304626 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4628 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304629 }
4630
4631 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304632 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304633 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4634
4635 pReqMsg->sessionId = pAdapter->sessionId;
4636 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4637
4638 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304639 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304640 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4641 goto fail;
4642 }
4643 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304644 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304645 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4646 pReqMsg->basePeriod);
4647
4648 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304649 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304650 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4651 goto fail;
4652 }
4653 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304654 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304655 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4656 pReqMsg->maxAPperScan);
4657
4658 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304659 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304660 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4661 goto fail;
4662 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304663 pReqMsg->reportThresholdPercent = nla_get_u8(
4664 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304665 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304666 pReqMsg->reportThresholdPercent);
4667
4668 /* Parse and fetch report threshold num scans */
4669 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4670 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4671 goto fail;
4672 }
4673 pReqMsg->reportThresholdNumScans = nla_get_u8(
4674 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4675 hddLog(LOG1, FL("Report Threshold num scans %d"),
4676 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304677
4678 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304679 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4681 goto fail;
4682 }
4683 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304684 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304685 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4686 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4687 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4688 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4689 }
4690 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4691 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304692
Dino Mycle6fb96c12014-06-10 11:52:40 +05304693 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4695 goto fail;
4696 }
4697
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304698 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304699
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304700 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4701 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304702
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304703 context = &pHddCtx->ext_scan_context;
4704 spin_lock(&hdd_context_lock);
4705 INIT_COMPLETION(context->response_event);
4706 context->request_id = request_id = pReqMsg->requestId;
4707 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304708
Dino Mycle6fb96c12014-06-10 11:52:40 +05304709 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4710 if (!HAL_STATUS_SUCCESS(status)) {
4711 hddLog(VOS_TRACE_LEVEL_ERROR,
4712 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304713 goto fail;
4714 }
4715
Srinivas Dasari91727c12016-03-23 17:59:06 +05304716 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4717
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304718 /* request was sent -- wait for the response */
4719 rc = wait_for_completion_timeout(&context->response_event,
4720 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4721
4722 if (!rc) {
4723 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4724 retval = -ETIMEDOUT;
4725 } else {
4726 spin_lock(&hdd_context_lock);
4727 if (context->request_id == request_id)
4728 retval = context->response_status;
4729 else
4730 retval = -EINVAL;
4731 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304732 }
4733
Dino Myclee8843b32014-07-04 14:21:45 +05304734 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304735 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304736 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304737
4738fail:
4739 vos_mem_free(pReqMsg);
4740 return -EINVAL;
4741}
4742
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304743/*
4744 * done with short names for the global vendor params
4745 * used by wlan_hdd_cfg80211_extscan_start()
4746 */
4747#undef PARAM_MAX
4748#undef PARAM_REQUEST_ID
4749#undef PARAM_BASE_PERIOD
4750#undef PARAMS_MAX_AP_PER_SCAN
4751#undef PARAMS_RPT_THRHLD_PERCENT
4752#undef PARAMS_RPT_THRHLD_NUM_SCANS
4753#undef PARAMS_NUM_BUCKETS
4754
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304755static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4756 struct wireless_dev *wdev,
4757 const void *data, int dataLen)
4758{
4759 int ret = 0;
4760
4761 vos_ssr_protect(__func__);
4762 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4763 vos_ssr_unprotect(__func__);
4764
4765 return ret;
4766}
4767
4768static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304769 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304770 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304771{
Dino Myclee8843b32014-07-04 14:21:45 +05304772 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304773 struct net_device *dev = wdev->netdev;
4774 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4775 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4776 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4777 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304778 int retval;
4779 unsigned long rc;
4780 struct hdd_ext_scan_context *context;
4781 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304782
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304783 ENTER();
4784
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304785 if (VOS_FTM_MODE == hdd_get_conparam()) {
4786 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4787 return -EINVAL;
4788 }
4789
Dino Mycle6fb96c12014-06-10 11:52:40 +05304790 status = wlan_hdd_validate_context(pHddCtx);
4791 if (0 != status)
4792 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304793 return -EINVAL;
4794 }
Dino Myclee8843b32014-07-04 14:21:45 +05304795 /* check the EXTScan Capability */
4796 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304797 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4798 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304799 {
4800 hddLog(VOS_TRACE_LEVEL_ERROR,
4801 FL("EXTScan not enabled/supported by Firmware"));
4802 return -EINVAL;
4803 }
4804
Dino Mycle6fb96c12014-06-10 11:52:40 +05304805 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4806 data, dataLen,
4807 wlan_hdd_extscan_config_policy)) {
4808 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4809 return -EINVAL;
4810 }
4811
4812 /* Parse and fetch request Id */
4813 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4814 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4815 return -EINVAL;
4816 }
4817
Dino Myclee8843b32014-07-04 14:21:45 +05304818 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304819 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304820 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304821
Dino Myclee8843b32014-07-04 14:21:45 +05304822 reqMsg.sessionId = pAdapter->sessionId;
4823 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304824
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304825 context = &pHddCtx->ext_scan_context;
4826 spin_lock(&hdd_context_lock);
4827 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304828 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304829 spin_unlock(&hdd_context_lock);
4830
Dino Myclee8843b32014-07-04 14:21:45 +05304831 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304832 if (!HAL_STATUS_SUCCESS(status)) {
4833 hddLog(VOS_TRACE_LEVEL_ERROR,
4834 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304835 return -EINVAL;
4836 }
4837
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304838 /* request was sent -- wait for the response */
4839 rc = wait_for_completion_timeout(&context->response_event,
4840 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4841
4842 if (!rc) {
4843 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4844 retval = -ETIMEDOUT;
4845 } else {
4846 spin_lock(&hdd_context_lock);
4847 if (context->request_id == request_id)
4848 retval = context->response_status;
4849 else
4850 retval = -EINVAL;
4851 spin_unlock(&hdd_context_lock);
4852 }
4853
4854 return retval;
4855
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304856 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304857 return 0;
4858}
4859
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304860static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4861 struct wireless_dev *wdev,
4862 const void *data, int dataLen)
4863{
4864 int ret = 0;
4865
4866 vos_ssr_protect(__func__);
4867 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4868 vos_ssr_unprotect(__func__);
4869
4870 return ret;
4871}
4872
4873static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304874 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304875 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304876{
Dino Myclee8843b32014-07-04 14:21:45 +05304877 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304878 struct net_device *dev = wdev->netdev;
4879 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4880 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4881 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4882 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304883 struct hdd_ext_scan_context *context;
4884 tANI_U32 request_id;
4885 unsigned long rc;
4886 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304887
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304888 ENTER();
4889
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304890 if (VOS_FTM_MODE == hdd_get_conparam()) {
4891 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4892 return -EINVAL;
4893 }
4894
Dino Mycle6fb96c12014-06-10 11:52:40 +05304895 status = wlan_hdd_validate_context(pHddCtx);
4896 if (0 != status)
4897 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304898 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304899 return -EINVAL;
4900 }
Dino Myclee8843b32014-07-04 14:21:45 +05304901 /* check the EXTScan Capability */
4902 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304903 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4904 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304905 {
4906 hddLog(VOS_TRACE_LEVEL_ERROR,
4907 FL("EXTScan not enabled/supported by Firmware"));
4908 return -EINVAL;
4909 }
4910
Dino Mycle6fb96c12014-06-10 11:52:40 +05304911 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4912 data, dataLen,
4913 wlan_hdd_extscan_config_policy)) {
4914 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4915 return -EINVAL;
4916 }
4917
4918 /* Parse and fetch request Id */
4919 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4920 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4921 return -EINVAL;
4922 }
4923
Dino Myclee8843b32014-07-04 14:21:45 +05304924 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304925 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304926 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304927
Dino Myclee8843b32014-07-04 14:21:45 +05304928 reqMsg.sessionId = pAdapter->sessionId;
4929 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304930
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304931 context = &pHddCtx->ext_scan_context;
4932 spin_lock(&hdd_context_lock);
4933 INIT_COMPLETION(context->response_event);
4934 context->request_id = request_id = reqMsg.requestId;
4935 spin_unlock(&hdd_context_lock);
4936
Dino Myclee8843b32014-07-04 14:21:45 +05304937 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304938 if (!HAL_STATUS_SUCCESS(status)) {
4939 hddLog(VOS_TRACE_LEVEL_ERROR,
4940 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304941 return -EINVAL;
4942 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304943
4944 /* request was sent -- wait for the response */
4945 rc = wait_for_completion_timeout(&context->response_event,
4946 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4947 if (!rc) {
4948 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4949 retval = -ETIMEDOUT;
4950 } else {
4951 spin_lock(&hdd_context_lock);
4952 if (context->request_id == request_id)
4953 retval = context->response_status;
4954 else
4955 retval = -EINVAL;
4956 spin_unlock(&hdd_context_lock);
4957 }
4958
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304959 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304960 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304961}
4962
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304963static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4964 struct wireless_dev *wdev,
4965 const void *data, int dataLen)
4966{
4967 int ret = 0;
4968
4969 vos_ssr_protect(__func__);
4970 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4971 vos_ssr_unprotect(__func__);
4972
4973 return ret;
4974}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304975#endif /* WLAN_FEATURE_EXTSCAN */
4976
Atul Mittal115287b2014-07-08 13:26:33 +05304977/*EXT TDLS*/
4978static const struct nla_policy
4979wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4980{
4981 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4982 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4983 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4984 {.type = NLA_S32 },
4985 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4986 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4987
4988};
4989
4990static const struct nla_policy
4991wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4992{
4993 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4994
4995};
4996
4997static const struct nla_policy
4998wlan_hdd_tdls_config_state_change_policy[
4999 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5000{
5001 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
5002 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5003 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305004 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5005 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5006 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305007
5008};
5009
5010static const struct nla_policy
5011wlan_hdd_tdls_config_get_status_policy[
5012 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5013{
5014 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5015 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5016 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305017 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5018 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5019 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305020
5021};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305022
5023static const struct nla_policy
5024wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5025{
5026 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5027};
5028
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305029static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305030 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305031 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305032 int data_len)
5033{
5034
5035 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5036 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5037
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305038 ENTER();
5039
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305040 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305041 return -EINVAL;
5042 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305043 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305044 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305045 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305046 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305047 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305048 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305049 return -ENOTSUPP;
5050 }
5051
5052 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5053 data, data_len, wlan_hdd_mac_config)) {
5054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5055 return -EINVAL;
5056 }
5057
5058 /* Parse and fetch mac address */
5059 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5061 return -EINVAL;
5062 }
5063
5064 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5065 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5066 VOS_MAC_ADDR_LAST_3_BYTES);
5067
Siddharth Bhal76972212014-10-15 16:22:51 +05305068 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5069
5070 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305071 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5072 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305073 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5074 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5075 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5076 {
5077 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5078 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5079 VOS_MAC_ADDRESS_LEN);
5080 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305081 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305082
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305083 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5084 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305085
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305086 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305087 return 0;
5088}
5089
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305090static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5091 struct wireless_dev *wdev,
5092 const void *data,
5093 int data_len)
5094{
5095 int ret = 0;
5096
5097 vos_ssr_protect(__func__);
5098 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5099 vos_ssr_unprotect(__func__);
5100
5101 return ret;
5102}
5103
5104static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305105 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305106 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305107 int data_len)
5108{
5109 u8 peer[6] = {0};
5110 struct net_device *dev = wdev->netdev;
5111 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5112 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5113 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5114 eHalStatus ret;
5115 tANI_S32 state;
5116 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305117 tANI_S32 global_operating_class = 0;
5118 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305119 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305120 int retVal;
5121
5122 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305123
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305124 if (!pAdapter) {
5125 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5126 return -EINVAL;
5127 }
5128
Atul Mittal115287b2014-07-08 13:26:33 +05305129 ret = wlan_hdd_validate_context(pHddCtx);
5130 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305131 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305132 return -EINVAL;
5133 }
5134 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305135 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305136 return -ENOTSUPP;
5137 }
5138 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5139 data, data_len,
5140 wlan_hdd_tdls_config_get_status_policy)) {
5141 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5142 return -EINVAL;
5143 }
5144
5145 /* Parse and fetch mac address */
5146 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5147 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5148 return -EINVAL;
5149 }
5150
5151 memcpy(peer, nla_data(
5152 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5153 sizeof(peer));
5154 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5155
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305156 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305157
Atul Mittal115287b2014-07-08 13:26:33 +05305158 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305159 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305160 NLMSG_HDRLEN);
5161
5162 if (!skb) {
5163 hddLog(VOS_TRACE_LEVEL_ERROR,
5164 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5165 return -EINVAL;
5166 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305167 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 +05305168 reason,
5169 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305170 global_operating_class,
5171 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305172 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305173 if (nla_put_s32(skb,
5174 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5175 state) ||
5176 nla_put_s32(skb,
5177 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5178 reason) ||
5179 nla_put_s32(skb,
5180 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5181 global_operating_class) ||
5182 nla_put_s32(skb,
5183 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5184 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305185
5186 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5187 goto nla_put_failure;
5188 }
5189
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305190 retVal = cfg80211_vendor_cmd_reply(skb);
5191 EXIT();
5192 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305193
5194nla_put_failure:
5195 kfree_skb(skb);
5196 return -EINVAL;
5197}
5198
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305199static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5200 struct wireless_dev *wdev,
5201 const void *data,
5202 int data_len)
5203{
5204 int ret = 0;
5205
5206 vos_ssr_protect(__func__);
5207 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5208 vos_ssr_unprotect(__func__);
5209
5210 return ret;
5211}
5212
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305213static int wlan_hdd_cfg80211_exttdls_callback(
5214#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5215 const tANI_U8* mac,
5216#else
5217 tANI_U8* mac,
5218#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305219 tANI_S32 state,
5220 tANI_S32 reason,
5221 void *ctx)
5222{
5223 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305224 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305225 tANI_S32 global_operating_class = 0;
5226 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305227 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305228
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305229 ENTER();
5230
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305231 if (!pAdapter) {
5232 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5233 return -EINVAL;
5234 }
5235
5236 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305237 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305239 return -EINVAL;
5240 }
5241
5242 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305243 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305244 return -ENOTSUPP;
5245 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305246 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5247#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5248 NULL,
5249#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305250 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5251 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5252 GFP_KERNEL);
5253
5254 if (!skb) {
5255 hddLog(VOS_TRACE_LEVEL_ERROR,
5256 FL("cfg80211_vendor_event_alloc failed"));
5257 return -EINVAL;
5258 }
5259 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305260 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5261 reason,
5262 state,
5263 global_operating_class,
5264 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305265 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5266 MAC_ADDR_ARRAY(mac));
5267
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305268 if (nla_put(skb,
5269 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5270 VOS_MAC_ADDR_SIZE, mac) ||
5271 nla_put_s32(skb,
5272 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5273 state) ||
5274 nla_put_s32(skb,
5275 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5276 reason) ||
5277 nla_put_s32(skb,
5278 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5279 channel) ||
5280 nla_put_s32(skb,
5281 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5282 global_operating_class)
5283 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305284 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5285 goto nla_put_failure;
5286 }
5287
5288 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305289 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305290 return (0);
5291
5292nla_put_failure:
5293 kfree_skb(skb);
5294 return -EINVAL;
5295}
5296
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305297static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305298 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305299 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305300 int data_len)
5301{
5302 u8 peer[6] = {0};
5303 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305304 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5305 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5306 eHalStatus status;
5307 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305308 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305309 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305310
5311 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305312
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305313 if (!dev) {
5314 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5315 return -EINVAL;
5316 }
5317
5318 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5319 if (!pAdapter) {
5320 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5321 return -EINVAL;
5322 }
5323
Atul Mittal115287b2014-07-08 13:26:33 +05305324 status = wlan_hdd_validate_context(pHddCtx);
5325 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305326 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305327 return -EINVAL;
5328 }
5329 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305330 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305331 return -ENOTSUPP;
5332 }
5333 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5334 data, data_len,
5335 wlan_hdd_tdls_config_enable_policy)) {
5336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5337 return -EINVAL;
5338 }
5339
5340 /* Parse and fetch mac address */
5341 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5342 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5343 return -EINVAL;
5344 }
5345
5346 memcpy(peer, nla_data(
5347 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5348 sizeof(peer));
5349 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5350
5351 /* Parse and fetch channel */
5352 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5354 return -EINVAL;
5355 }
5356 pReqMsg.channel = nla_get_s32(
5357 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5358 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5359
5360 /* Parse and fetch global operating class */
5361 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5362 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5363 return -EINVAL;
5364 }
5365 pReqMsg.global_operating_class = nla_get_s32(
5366 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5367 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5368 pReqMsg.global_operating_class);
5369
5370 /* Parse and fetch latency ms */
5371 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5373 return -EINVAL;
5374 }
5375 pReqMsg.max_latency_ms = nla_get_s32(
5376 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5377 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5378 pReqMsg.max_latency_ms);
5379
5380 /* Parse and fetch required bandwidth kbps */
5381 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5382 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5383 return -EINVAL;
5384 }
5385
5386 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5387 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5388 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5389 pReqMsg.min_bandwidth_kbps);
5390
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305391 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305392 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305393 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305394 wlan_hdd_cfg80211_exttdls_callback);
5395
5396 EXIT();
5397 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305398}
5399
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305400static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5401 struct wireless_dev *wdev,
5402 const void *data,
5403 int data_len)
5404{
5405 int ret = 0;
5406
5407 vos_ssr_protect(__func__);
5408 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5409 vos_ssr_unprotect(__func__);
5410
5411 return ret;
5412}
5413
5414static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305415 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305416 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305417 int data_len)
5418{
5419 u8 peer[6] = {0};
5420 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305421 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5422 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5423 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305424 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305425 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305426
5427 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305428
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305429 if (!dev) {
5430 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5431 return -EINVAL;
5432 }
5433
5434 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5435 if (!pAdapter) {
5436 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5437 return -EINVAL;
5438 }
5439
Atul Mittal115287b2014-07-08 13:26:33 +05305440 status = wlan_hdd_validate_context(pHddCtx);
5441 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305443 return -EINVAL;
5444 }
5445 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305446 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305447 return -ENOTSUPP;
5448 }
5449 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5450 data, data_len,
5451 wlan_hdd_tdls_config_disable_policy)) {
5452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5453 return -EINVAL;
5454 }
5455 /* Parse and fetch mac address */
5456 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5458 return -EINVAL;
5459 }
5460
5461 memcpy(peer, nla_data(
5462 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5463 sizeof(peer));
5464 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5465
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305466 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5467
5468 EXIT();
5469 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305470}
5471
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305472static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5473 struct wireless_dev *wdev,
5474 const void *data,
5475 int data_len)
5476{
5477 int ret = 0;
5478
5479 vos_ssr_protect(__func__);
5480 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5481 vos_ssr_unprotect(__func__);
5482
5483 return ret;
5484}
5485
Dasari Srinivas7875a302014-09-26 17:50:57 +05305486static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305487__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305488 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305489 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305490{
5491 struct net_device *dev = wdev->netdev;
5492 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5493 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5494 struct sk_buff *skb = NULL;
5495 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305496 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305497
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305498 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305499
5500 ret = wlan_hdd_validate_context(pHddCtx);
5501 if (0 != ret)
5502 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305503 return ret;
5504 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305505 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5506 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5507 fset |= WIFI_FEATURE_INFRA;
5508 }
5509
5510 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5511 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5512 fset |= WIFI_FEATURE_INFRA_5G;
5513 }
5514
5515#ifdef WLAN_FEATURE_P2P
5516 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5517 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5518 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5519 fset |= WIFI_FEATURE_P2P;
5520 }
5521#endif
5522
5523 /* Soft-AP is supported currently by default */
5524 fset |= WIFI_FEATURE_SOFT_AP;
5525
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305526 /* HOTSPOT is a supplicant feature, enable it by default */
5527 fset |= WIFI_FEATURE_HOTSPOT;
5528
Dasari Srinivas7875a302014-09-26 17:50:57 +05305529#ifdef WLAN_FEATURE_EXTSCAN
5530 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305531 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5532 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5533 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305534 fset |= WIFI_FEATURE_EXTSCAN;
5535 }
5536#endif
5537
Dasari Srinivas7875a302014-09-26 17:50:57 +05305538 if (sme_IsFeatureSupportedByFW(NAN)) {
5539 hddLog(LOG1, FL("NAN is supported by firmware"));
5540 fset |= WIFI_FEATURE_NAN;
5541 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305542
5543 /* D2D RTT is not supported currently by default */
5544 if (sme_IsFeatureSupportedByFW(RTT)) {
5545 hddLog(LOG1, FL("RTT is supported by firmware"));
5546 fset |= WIFI_FEATURE_D2AP_RTT;
5547 }
5548
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305549 if (sme_IsFeatureSupportedByFW(RTT3)) {
5550 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5551 fset |= WIFI_FEATURE_RTT3;
5552 }
5553
Dasari Srinivas7875a302014-09-26 17:50:57 +05305554#ifdef FEATURE_WLAN_BATCH_SCAN
5555 if (fset & WIFI_FEATURE_EXTSCAN) {
5556 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5557 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5558 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5559 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5560 fset |= WIFI_FEATURE_BATCH_SCAN;
5561 }
5562#endif
5563
5564#ifdef FEATURE_WLAN_SCAN_PNO
5565 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5566 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5567 hddLog(LOG1, FL("PNO is supported by firmware"));
5568 fset |= WIFI_FEATURE_PNO;
5569 }
5570#endif
5571
5572 /* STA+STA is supported currently by default */
5573 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5574
5575#ifdef FEATURE_WLAN_TDLS
5576 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5577 sme_IsFeatureSupportedByFW(TDLS)) {
5578 hddLog(LOG1, FL("TDLS is supported by firmware"));
5579 fset |= WIFI_FEATURE_TDLS;
5580 }
5581
5582 /* TDLS_OFFCHANNEL is not supported currently by default */
5583#endif
5584
5585#ifdef WLAN_AP_STA_CONCURRENCY
5586 /* AP+STA concurrency is supported currently by default */
5587 fset |= WIFI_FEATURE_AP_STA;
5588#endif
5589
Mukul Sharma5add0532015-08-17 15:57:47 +05305590#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5591 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5592 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5593#endif
5594
Dasari Srinivas7875a302014-09-26 17:50:57 +05305595 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5596 NLMSG_HDRLEN);
5597
5598 if (!skb) {
5599 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5600 return -EINVAL;
5601 }
5602 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5603
5604 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5605 hddLog(LOGE, FL("nla put fail"));
5606 goto nla_put_failure;
5607 }
5608
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305609 ret = cfg80211_vendor_cmd_reply(skb);
5610 EXIT();
5611 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305612
5613nla_put_failure:
5614 kfree_skb(skb);
5615 return -EINVAL;
5616}
5617
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305618static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305619wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5620 struct wireless_dev *wdev,
5621 const void *data, int data_len)
5622{
5623 int ret = 0;
5624
5625 vos_ssr_protect(__func__);
5626 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5627 vos_ssr_unprotect(__func__);
5628
5629 return ret;
5630}
5631
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305632
5633static const struct
5634nla_policy
5635qca_wlan_vendor_wifi_logger_get_ring_data_policy
5636[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5637 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5638 = {.type = NLA_U32 },
5639};
5640
5641static int
5642 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5643 struct wireless_dev *wdev,
5644 const void *data,
5645 int data_len)
5646{
5647 int ret;
5648 VOS_STATUS status;
5649 uint32_t ring_id;
5650 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5651 struct nlattr *tb
5652 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5653
5654 ENTER();
5655
5656 ret = wlan_hdd_validate_context(hdd_ctx);
5657 if (0 != ret) {
5658 return ret;
5659 }
5660
5661 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5662 data, data_len,
5663 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5664 hddLog(LOGE, FL("Invalid attribute"));
5665 return -EINVAL;
5666 }
5667
5668 /* Parse and fetch ring id */
5669 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5670 hddLog(LOGE, FL("attr ATTR failed"));
5671 return -EINVAL;
5672 }
5673
5674 ring_id = nla_get_u32(
5675 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5676
5677 hddLog(LOG1, FL("Bug report triggered by framework"));
5678
5679 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5680 WLAN_LOG_INDICATOR_FRAMEWORK,
5681 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305682 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305683 );
5684 if (VOS_STATUS_SUCCESS != status) {
5685 hddLog(LOGE, FL("Failed to trigger bug report"));
5686
5687 return -EINVAL;
5688 }
5689
5690 return 0;
5691
5692
5693}
5694
5695
5696static int
5697 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5698 struct wireless_dev *wdev,
5699 const void *data,
5700 int data_len)
5701{
5702 int ret = 0;
5703
5704 vos_ssr_protect(__func__);
5705 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5706 wdev, data, data_len);
5707 vos_ssr_unprotect(__func__);
5708
5709 return ret;
5710
5711}
5712
5713
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305714static int
5715__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305716 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305717 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305718{
5719 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5720 uint8_t i, feature_sets, max_feature_sets;
5721 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5722 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305723 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5724 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305725
5726 ENTER();
5727
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305728 ret = wlan_hdd_validate_context(pHddCtx);
5729 if (0 != ret)
5730 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305731 return ret;
5732 }
5733
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305734 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5735 data, data_len, NULL)) {
5736 hddLog(LOGE, FL("Invalid ATTR"));
5737 return -EINVAL;
5738 }
5739
5740 /* Parse and fetch max feature set */
5741 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5742 hddLog(LOGE, FL("Attr max feature set size failed"));
5743 return -EINVAL;
5744 }
5745 max_feature_sets = nla_get_u32(
5746 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5747 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5748
5749 /* Fill feature combination matrix */
5750 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305751 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5752 WIFI_FEATURE_P2P;
5753
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305754 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5755 WIFI_FEATURE_SOFT_AP;
5756
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305757 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5758 WIFI_FEATURE_SOFT_AP;
5759
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305760 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5761 WIFI_FEATURE_SOFT_AP |
5762 WIFI_FEATURE_P2P;
5763
5764 /* Add more feature combinations here */
5765
5766 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5767 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5768 hddLog(LOG1, "Feature set matrix");
5769 for (i = 0; i < feature_sets; i++)
5770 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5771
5772 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5773 sizeof(u32) * feature_sets +
5774 NLMSG_HDRLEN);
5775
5776 if (reply_skb) {
5777 if (nla_put_u32(reply_skb,
5778 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5779 feature_sets) ||
5780 nla_put(reply_skb,
5781 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5782 sizeof(u32) * feature_sets, feature_set_matrix)) {
5783 hddLog(LOGE, FL("nla put fail"));
5784 kfree_skb(reply_skb);
5785 return -EINVAL;
5786 }
5787
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305788 ret = cfg80211_vendor_cmd_reply(reply_skb);
5789 EXIT();
5790 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305791 }
5792 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5793 return -ENOMEM;
5794
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305795}
5796
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305797static int
5798wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5799 struct wireless_dev *wdev,
5800 const void *data, int data_len)
5801{
5802 int ret = 0;
5803
5804 vos_ssr_protect(__func__);
5805 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5806 data_len);
5807 vos_ssr_unprotect(__func__);
5808
5809 return ret;
5810}
5811
c_manjeecfd1efb2015-09-25 19:32:34 +05305812
5813static int
5814__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5815 struct wireless_dev *wdev,
5816 const void *data, int data_len)
5817{
5818 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5819 int ret;
5820 ENTER();
5821
5822 ret = wlan_hdd_validate_context(pHddCtx);
5823 if (0 != ret)
5824 {
5825 return ret;
5826 }
5827
5828 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5829 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5830 {
5831 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5832 return -EINVAL;
5833 }
5834 /*call common API for FW mem dump req*/
5835 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5836
Abhishek Singhc783fa72015-12-09 18:07:34 +05305837 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305838 {
5839 /*indicate to userspace the status of fw mem dump */
5840 wlan_indicate_mem_dump_complete(true);
5841 }
5842 else
5843 {
5844 /*else send failure to userspace */
5845 wlan_indicate_mem_dump_complete(false);
5846 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305847 EXIT();
5848 return ret;
5849}
5850
5851/**
5852 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5853 * @wiphy: pointer to wireless wiphy structure.
5854 * @wdev: pointer to wireless_dev structure.
5855 * @data: Pointer to the NL data.
5856 * @data_len:Length of @data
5857 *
5858 * This is called when wlan driver needs to get the firmware memory dump
5859 * via vendor specific command.
5860 *
5861 * Return: 0 on success, error number otherwise.
5862 */
5863
5864static int
5865wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5866 struct wireless_dev *wdev,
5867 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305868{
5869 int ret = 0;
5870 vos_ssr_protect(__func__);
5871 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5872 data_len);
5873 vos_ssr_unprotect(__func__);
5874 return ret;
5875}
c_manjeecfd1efb2015-09-25 19:32:34 +05305876
Sushant Kaushik8e644982015-09-23 12:18:54 +05305877static const struct
5878nla_policy
5879qca_wlan_vendor_wifi_logger_start_policy
5880[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5881 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5882 = {.type = NLA_U32 },
5883 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5884 = {.type = NLA_U32 },
5885 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5886 = {.type = NLA_U32 },
5887};
5888
5889/**
5890 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5891 * or disable the collection of packet statistics from the firmware
5892 * @wiphy: WIPHY structure pointer
5893 * @wdev: Wireless device structure pointer
5894 * @data: Pointer to the data received
5895 * @data_len: Length of the data received
5896 *
5897 * This function is used to enable or disable the collection of packet
5898 * statistics from the firmware
5899 *
5900 * Return: 0 on success and errno on failure
5901 */
5902static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5903 struct wireless_dev *wdev,
5904 const void *data,
5905 int data_len)
5906{
5907 eHalStatus status;
5908 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5909 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5910 tAniWifiStartLog start_log;
5911
5912 status = wlan_hdd_validate_context(hdd_ctx);
5913 if (0 != status) {
5914 return -EINVAL;
5915 }
5916
5917 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5918 data, data_len,
5919 qca_wlan_vendor_wifi_logger_start_policy)) {
5920 hddLog(LOGE, FL("Invalid attribute"));
5921 return -EINVAL;
5922 }
5923
5924 /* Parse and fetch ring id */
5925 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5926 hddLog(LOGE, FL("attr ATTR failed"));
5927 return -EINVAL;
5928 }
5929 start_log.ringId = nla_get_u32(
5930 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5931 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5932
5933 /* Parse and fetch verbose level */
5934 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5935 hddLog(LOGE, FL("attr verbose_level failed"));
5936 return -EINVAL;
5937 }
5938 start_log.verboseLevel = nla_get_u32(
5939 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5940 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5941
5942 /* Parse and fetch flag */
5943 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5944 hddLog(LOGE, FL("attr flag failed"));
5945 return -EINVAL;
5946 }
5947 start_log.flag = nla_get_u32(
5948 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5949 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5950
5951 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305952 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5953 !vos_isPktStatsEnabled()))
5954
Sushant Kaushik8e644982015-09-23 12:18:54 +05305955 {
5956 hddLog(LOGE, FL("per pkt stats not enabled"));
5957 return -EINVAL;
5958 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305959
Sushant Kaushik33200572015-08-05 16:46:20 +05305960 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305961 return 0;
5962}
5963
5964/**
5965 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5966 * or disable the collection of packet statistics from the firmware
5967 * @wiphy: WIPHY structure pointer
5968 * @wdev: Wireless device structure pointer
5969 * @data: Pointer to the data received
5970 * @data_len: Length of the data received
5971 *
5972 * This function is used to enable or disable the collection of packet
5973 * statistics from the firmware
5974 *
5975 * Return: 0 on success and errno on failure
5976 */
5977static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5978 struct wireless_dev *wdev,
5979 const void *data,
5980 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05305981{
5982 int ret = 0;
5983
5984 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305985
5986 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
5987 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05305988 vos_ssr_unprotect(__func__);
5989
5990 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05305991}
5992
5993
Agarwal Ashish738843c2014-09-25 12:27:56 +05305994static const struct nla_policy
5995wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5996 +1] =
5997{
5998 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5999};
6000
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306001static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306002 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306003 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306004 int data_len)
6005{
6006 struct net_device *dev = wdev->netdev;
6007 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6008 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6009 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6010 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6011 eHalStatus status;
6012 u32 dfsFlag = 0;
6013
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306014 ENTER();
6015
Agarwal Ashish738843c2014-09-25 12:27:56 +05306016 status = wlan_hdd_validate_context(pHddCtx);
6017 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306018 return -EINVAL;
6019 }
6020 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6021 data, data_len,
6022 wlan_hdd_set_no_dfs_flag_config_policy)) {
6023 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6024 return -EINVAL;
6025 }
6026
6027 /* Parse and fetch required bandwidth kbps */
6028 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6029 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6030 return -EINVAL;
6031 }
6032
6033 dfsFlag = nla_get_u32(
6034 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6035 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6036 dfsFlag);
6037
6038 pHddCtx->disable_dfs_flag = dfsFlag;
6039
6040 sme_disable_dfs_channel(hHal, dfsFlag);
6041 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306042
6043 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306044 return 0;
6045}
Atul Mittal115287b2014-07-08 13:26:33 +05306046
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306047static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6048 struct wireless_dev *wdev,
6049 const void *data,
6050 int data_len)
6051{
6052 int ret = 0;
6053
6054 vos_ssr_protect(__func__);
6055 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6056 vos_ssr_unprotect(__func__);
6057
6058 return ret;
6059
6060}
6061
Mukul Sharma2a271632014-10-13 14:59:01 +05306062const struct
6063nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6064{
6065 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6066 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6067};
6068
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306069static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306070 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306071{
6072
6073 u8 bssid[6] = {0};
6074 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6075 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6076 eHalStatus status = eHAL_STATUS_SUCCESS;
6077 v_U32_t isFwrRoamEnabled = FALSE;
6078 int ret;
6079
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306080 ENTER();
6081
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306082 ret = wlan_hdd_validate_context(pHddCtx);
6083 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306084 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306085 }
6086
6087 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6088 data, data_len,
6089 qca_wlan_vendor_attr);
6090 if (ret){
6091 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6092 return -EINVAL;
6093 }
6094
6095 /* Parse and fetch Enable flag */
6096 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6097 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6098 return -EINVAL;
6099 }
6100
6101 isFwrRoamEnabled = nla_get_u32(
6102 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6103
6104 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6105
6106 /* Parse and fetch bssid */
6107 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6108 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6109 return -EINVAL;
6110 }
6111
6112 memcpy(bssid, nla_data(
6113 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6114 sizeof(bssid));
6115 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6116
6117 //Update roaming
6118 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306119 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05306120 return status;
6121}
6122
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306123static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6124 struct wireless_dev *wdev, const void *data, int data_len)
6125{
6126 int ret = 0;
6127
6128 vos_ssr_protect(__func__);
6129 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6130 vos_ssr_unprotect(__func__);
6131
6132 return ret;
6133}
6134
Sushant Kaushik847890c2015-09-28 16:05:17 +05306135static const struct
6136nla_policy
6137qca_wlan_vendor_get_wifi_info_policy[
6138 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6139 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6140 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6141};
6142
6143
6144/**
6145 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6146 * @wiphy: pointer to wireless wiphy structure.
6147 * @wdev: pointer to wireless_dev structure.
6148 * @data: Pointer to the data to be passed via vendor interface
6149 * @data_len:Length of the data to be passed
6150 *
6151 * This is called when wlan driver needs to send wifi driver related info
6152 * (driver/fw version) to the user space application upon request.
6153 *
6154 * Return: Return the Success or Failure code.
6155 */
6156static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6157 struct wireless_dev *wdev,
6158 const void *data, int data_len)
6159{
6160 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6161 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6162 tSirVersionString version;
6163 uint32 version_len;
6164 uint8 attr;
6165 int status;
6166 struct sk_buff *reply_skb = NULL;
6167
6168 if (VOS_FTM_MODE == hdd_get_conparam()) {
6169 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6170 return -EINVAL;
6171 }
6172
6173 status = wlan_hdd_validate_context(hdd_ctx);
6174 if (0 != status) {
6175 hddLog(LOGE, FL("HDD context is not valid"));
6176 return -EINVAL;
6177 }
6178
6179 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6180 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6181 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6182 return -EINVAL;
6183 }
6184
6185 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6186 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6187 QWLAN_VERSIONSTR);
6188 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6189 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6190 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6191 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6192 hdd_ctx->fw_Version);
6193 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6194 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6195 } else {
6196 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6197 return -EINVAL;
6198 }
6199
6200 version_len = strlen(version);
6201 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6202 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6203 if (!reply_skb) {
6204 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6205 return -ENOMEM;
6206 }
6207
6208 if (nla_put(reply_skb, attr, version_len, version)) {
6209 hddLog(LOGE, FL("nla put fail"));
6210 kfree_skb(reply_skb);
6211 return -EINVAL;
6212 }
6213
6214 return cfg80211_vendor_cmd_reply(reply_skb);
6215}
6216
6217/**
6218 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6219 * @wiphy: pointer to wireless wiphy structure.
6220 * @wdev: pointer to wireless_dev structure.
6221 * @data: Pointer to the data to be passed via vendor interface
6222 * @data_len:Length of the data to be passed
6223 * @data_len: Length of the data received
6224 *
6225 * This function is used to enable or disable the collection of packet
6226 * statistics from the firmware
6227 *
6228 * Return: 0 on success and errno on failure
6229 */
6230
6231static int
6232wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6233 struct wireless_dev *wdev,
6234 const void *data, int data_len)
6235
6236
6237{
6238 int ret = 0;
6239
6240 vos_ssr_protect(__func__);
6241 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6242 wdev, data, data_len);
6243 vos_ssr_unprotect(__func__);
6244
6245 return ret;
6246}
6247
6248
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306249/*
6250 * define short names for the global vendor params
6251 * used by __wlan_hdd_cfg80211_monitor_rssi()
6252 */
6253#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6254#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6255#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6256#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6257#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6258
6259/**---------------------------------------------------------------------------
6260
6261 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6262 monitor start is completed successfully.
6263
6264 \return - None
6265
6266 --------------------------------------------------------------------------*/
6267void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6268{
6269 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6270
6271 if (NULL == pHddCtx)
6272 {
6273 hddLog(VOS_TRACE_LEVEL_ERROR,
6274 "%s: HDD context is NULL",__func__);
6275 return;
6276 }
6277
6278 if (VOS_STATUS_SUCCESS == status)
6279 {
6280 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6281 }
6282 else
6283 {
6284 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6285 }
6286
6287 return;
6288}
6289
6290/**---------------------------------------------------------------------------
6291
6292 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6293 stop is completed successfully.
6294
6295 \return - None
6296
6297 --------------------------------------------------------------------------*/
6298void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6299{
6300 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6301
6302 if (NULL == pHddCtx)
6303 {
6304 hddLog(VOS_TRACE_LEVEL_ERROR,
6305 "%s: HDD context is NULL",__func__);
6306 return;
6307 }
6308
6309 if (VOS_STATUS_SUCCESS == status)
6310 {
6311 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6312 }
6313 else
6314 {
6315 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6316 }
6317
6318 return;
6319}
6320
6321/**
6322 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6323 * @wiphy: Pointer to wireless phy
6324 * @wdev: Pointer to wireless device
6325 * @data: Pointer to data
6326 * @data_len: Data length
6327 *
6328 * Return: 0 on success, negative errno on failure
6329 */
6330
6331static int
6332__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6333 struct wireless_dev *wdev,
6334 const void *data,
6335 int data_len)
6336{
6337 struct net_device *dev = wdev->netdev;
6338 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6339 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6340 hdd_station_ctx_t *pHddStaCtx;
6341 struct nlattr *tb[PARAM_MAX + 1];
6342 tpSirRssiMonitorReq pReq;
6343 eHalStatus status;
6344 int ret;
6345 uint32_t control;
6346 static const struct nla_policy policy[PARAM_MAX + 1] = {
6347 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6348 [PARAM_CONTROL] = { .type = NLA_U32 },
6349 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6350 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6351 };
6352
6353 ENTER();
6354
6355 ret = wlan_hdd_validate_context(hdd_ctx);
6356 if (0 != ret) {
6357 return -EINVAL;
6358 }
6359
6360 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6361 hddLog(LOGE, FL("Not in Connected state!"));
6362 return -ENOTSUPP;
6363 }
6364
6365 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6366 hddLog(LOGE, FL("Invalid ATTR"));
6367 return -EINVAL;
6368 }
6369
6370 if (!tb[PARAM_REQUEST_ID]) {
6371 hddLog(LOGE, FL("attr request id failed"));
6372 return -EINVAL;
6373 }
6374
6375 if (!tb[PARAM_CONTROL]) {
6376 hddLog(LOGE, FL("attr control failed"));
6377 return -EINVAL;
6378 }
6379
6380 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6381
6382 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6383 if(NULL == pReq)
6384 {
6385 hddLog(LOGE,
6386 FL("vos_mem_alloc failed "));
6387 return eHAL_STATUS_FAILED_ALLOC;
6388 }
6389 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6390
6391 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6392 pReq->sessionId = pAdapter->sessionId;
6393 pReq->rssiMonitorCbContext = hdd_ctx;
6394 control = nla_get_u32(tb[PARAM_CONTROL]);
6395 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6396
6397 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6398 pReq->requestId, pReq->sessionId, control);
6399
6400 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6401 if (!tb[PARAM_MIN_RSSI]) {
6402 hddLog(LOGE, FL("attr min rssi failed"));
6403 return -EINVAL;
6404 }
6405
6406 if (!tb[PARAM_MAX_RSSI]) {
6407 hddLog(LOGE, FL("attr max rssi failed"));
6408 return -EINVAL;
6409 }
6410
6411 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6412 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6413 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6414
6415 if (!(pReq->minRssi < pReq->maxRssi)) {
6416 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6417 pReq->minRssi, pReq->maxRssi);
6418 return -EINVAL;
6419 }
6420 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6421 pReq->minRssi, pReq->maxRssi);
6422 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6423
6424 }
6425 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6426 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6427 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6428 }
6429 else {
6430 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
6431 return -EINVAL;
6432 }
6433
6434 if (!HAL_STATUS_SUCCESS(status)) {
6435 hddLog(LOGE,
6436 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
6437 return -EINVAL;
6438 }
6439
6440 return 0;
6441}
6442
6443/*
6444 * done with short names for the global vendor params
6445 * used by __wlan_hdd_cfg80211_monitor_rssi()
6446 */
6447#undef PARAM_MAX
6448#undef PARAM_CONTROL
6449#undef PARAM_REQUEST_ID
6450#undef PARAM_MAX_RSSI
6451#undef PARAM_MIN_RSSI
6452
6453/**
6454 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6455 * @wiphy: wiphy structure pointer
6456 * @wdev: Wireless device structure pointer
6457 * @data: Pointer to the data received
6458 * @data_len: Length of @data
6459 *
6460 * Return: 0 on success; errno on failure
6461 */
6462static int
6463wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6464 const void *data, int data_len)
6465{
6466 int ret;
6467
6468 vos_ssr_protect(__func__);
6469 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6470 vos_ssr_unprotect(__func__);
6471
6472 return ret;
6473}
6474
6475/**
6476 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6477 * @hddctx: HDD context
6478 * @data: rssi breached event data
6479 *
6480 * This function reads the rssi breached event %data and fill in the skb with
6481 * NL attributes and send up the NL event.
6482 * This callback execute in atomic context and must not invoke any
6483 * blocking calls.
6484 *
6485 * Return: none
6486 */
6487void hdd_rssi_threshold_breached_cb(void *hddctx,
6488 struct rssi_breach_event *data)
6489{
6490 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6491 int status;
6492 struct sk_buff *skb;
6493
6494 ENTER();
6495 status = wlan_hdd_validate_context(pHddCtx);
6496
6497 if (0 != status) {
6498 return;
6499 }
6500
6501 if (!data) {
6502 hddLog(LOGE, FL("data is null"));
6503 return;
6504 }
6505
6506 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6507#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6508 NULL,
6509#endif
6510 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6511 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6512 GFP_KERNEL);
6513
6514 if (!skb) {
6515 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6516 return;
6517 }
6518
6519 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6520 data->request_id, data->curr_rssi);
6521 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6522 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6523
6524 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6525 data->request_id) ||
6526 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6527 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6528 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6529 data->curr_rssi)) {
6530 hddLog(LOGE, FL("nla put fail"));
6531 goto fail;
6532 }
6533
6534 cfg80211_vendor_event(skb, GFP_KERNEL);
6535 return;
6536
6537fail:
6538 kfree_skb(skb);
6539 return;
6540}
6541
6542
6543
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306544/**
6545 * __wlan_hdd_cfg80211_setband() - set band
6546 * @wiphy: Pointer to wireless phy
6547 * @wdev: Pointer to wireless device
6548 * @data: Pointer to data
6549 * @data_len: Data length
6550 *
6551 * Return: 0 on success, negative errno on failure
6552 */
6553static int
6554__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6555 struct wireless_dev *wdev,
6556 const void *data,
6557 int data_len)
6558{
6559 struct net_device *dev = wdev->netdev;
6560 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6561 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6562 int ret;
6563 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6564 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6565
6566 ENTER();
6567
6568 ret = wlan_hdd_validate_context(hdd_ctx);
6569 if (0 != ret) {
6570 hddLog(LOGE, FL("HDD context is not valid"));
6571 return ret;
6572 }
6573
6574 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6575 policy)) {
6576 hddLog(LOGE, FL("Invalid ATTR"));
6577 return -EINVAL;
6578 }
6579
6580 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6581 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6582 return -EINVAL;
6583 }
6584
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306585 hdd_ctx->isSetBandByNL = TRUE;
6586 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306587 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306588 hdd_ctx->isSetBandByNL = FALSE;
6589
6590 EXIT();
6591 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306592}
6593
6594/**
6595 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6596 * @wiphy: wiphy structure pointer
6597 * @wdev: Wireless device structure pointer
6598 * @data: Pointer to the data received
6599 * @data_len: Length of @data
6600 *
6601 * Return: 0 on success; errno on failure
6602 */
6603static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6604 struct wireless_dev *wdev,
6605 const void *data,
6606 int data_len)
6607{
6608 int ret = 0;
6609
6610 vos_ssr_protect(__func__);
6611 ret = __wlan_hdd_cfg80211_setband(wiphy,
6612 wdev, data, data_len);
6613 vos_ssr_unprotect(__func__);
6614
6615 return ret;
6616}
6617
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306618#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6619/**
6620 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6621 * @hdd_ctx: HDD context
6622 * @request_id: [input] request id
6623 * @pattern_id: [output] pattern id
6624 *
6625 * This function loops through request id to pattern id array
6626 * if the slot is available, store the request id and return pattern id
6627 * if entry exists, return the pattern id
6628 *
6629 * Return: 0 on success and errno on failure
6630 */
6631static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6632 uint32_t request_id,
6633 uint8_t *pattern_id)
6634{
6635 uint32_t i;
6636
6637 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6638 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6639 {
6640 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6641 {
6642 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6643 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6644 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6645 return 0;
6646 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6647 request_id) {
6648 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6649 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6650 return 0;
6651 }
6652 }
6653 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6654 return -EINVAL;
6655}
6656
6657/**
6658 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6659 * @hdd_ctx: HDD context
6660 * @request_id: [input] request id
6661 * @pattern_id: [output] pattern id
6662 *
6663 * This function loops through request id to pattern id array
6664 * reset request id to 0 (slot available again) and
6665 * return pattern id
6666 *
6667 * Return: 0 on success and errno on failure
6668 */
6669static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6670 uint32_t request_id,
6671 uint8_t *pattern_id)
6672{
6673 uint32_t i;
6674
6675 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6676 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6677 {
6678 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6679 {
6680 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6681 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6682 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6683 return 0;
6684 }
6685 }
6686 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6687 return -EINVAL;
6688}
6689
6690
6691/*
6692 * define short names for the global vendor params
6693 * used by __wlan_hdd_cfg80211_offloaded_packets()
6694 */
6695#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6696#define PARAM_REQUEST_ID \
6697 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6698#define PARAM_CONTROL \
6699 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6700#define PARAM_IP_PACKET \
6701 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6702#define PARAM_SRC_MAC_ADDR \
6703 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6704#define PARAM_DST_MAC_ADDR \
6705 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6706#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6707
6708/**
6709 * wlan_hdd_add_tx_ptrn() - add tx pattern
6710 * @adapter: adapter pointer
6711 * @hdd_ctx: hdd context
6712 * @tb: nl attributes
6713 *
6714 * This function reads the NL attributes and forms a AddTxPtrn message
6715 * posts it to SME.
6716 *
6717 */
6718static int
6719wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6720 struct nlattr **tb)
6721{
6722 struct sSirAddPeriodicTxPtrn *add_req;
6723 eHalStatus status;
6724 uint32_t request_id, ret, len;
6725 uint8_t pattern_id = 0;
6726 v_MACADDR_t dst_addr;
6727 uint16_t eth_type = htons(ETH_P_IP);
6728
6729 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6730 {
6731 hddLog(LOGE, FL("Not in Connected state!"));
6732 return -ENOTSUPP;
6733 }
6734
6735 add_req = vos_mem_malloc(sizeof(*add_req));
6736 if (!add_req)
6737 {
6738 hddLog(LOGE, FL("memory allocation failed"));
6739 return -ENOMEM;
6740 }
6741
6742 /* Parse and fetch request Id */
6743 if (!tb[PARAM_REQUEST_ID])
6744 {
6745 hddLog(LOGE, FL("attr request id failed"));
6746 goto fail;
6747 }
6748
6749 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6750 hddLog(LOG1, FL("Request Id: %u"), request_id);
6751 if (request_id == 0)
6752 {
6753 hddLog(LOGE, FL("request_id cannot be zero"));
6754 return -EINVAL;
6755 }
6756
6757 if (!tb[PARAM_PERIOD])
6758 {
6759 hddLog(LOGE, FL("attr period failed"));
6760 goto fail;
6761 }
6762 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6763 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6764 if (add_req->usPtrnIntervalMs == 0)
6765 {
6766 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6767 goto fail;
6768 }
6769
6770 if (!tb[PARAM_SRC_MAC_ADDR])
6771 {
6772 hddLog(LOGE, FL("attr source mac address failed"));
6773 goto fail;
6774 }
6775 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6776 VOS_MAC_ADDR_SIZE);
6777 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6778 MAC_ADDR_ARRAY(add_req->macAddress));
6779
6780 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6781 VOS_MAC_ADDR_SIZE))
6782 {
6783 hddLog(LOGE,
6784 FL("input src mac address and connected ap bssid are different"));
6785 goto fail;
6786 }
6787
6788 if (!tb[PARAM_DST_MAC_ADDR])
6789 {
6790 hddLog(LOGE, FL("attr dst mac address failed"));
6791 goto fail;
6792 }
6793 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6794 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6795 MAC_ADDR_ARRAY(dst_addr.bytes));
6796
6797 if (!tb[PARAM_IP_PACKET])
6798 {
6799 hddLog(LOGE, FL("attr ip packet failed"));
6800 goto fail;
6801 }
6802 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6803 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6804
6805 if (add_req->ucPtrnSize < 0 ||
6806 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6807 HDD_ETH_HEADER_LEN))
6808 {
6809 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6810 add_req->ucPtrnSize);
6811 goto fail;
6812 }
6813
6814 len = 0;
6815 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6816 len += VOS_MAC_ADDR_SIZE;
6817 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6818 VOS_MAC_ADDR_SIZE);
6819 len += VOS_MAC_ADDR_SIZE;
6820 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6821 len += 2;
6822
6823 /*
6824 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6825 * ------------------------------------------------------------
6826 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6827 * ------------------------------------------------------------
6828 */
6829 vos_mem_copy(&add_req->ucPattern[len],
6830 nla_data(tb[PARAM_IP_PACKET]),
6831 add_req->ucPtrnSize);
6832 add_req->ucPtrnSize += len;
6833
6834 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6835 add_req->ucPattern, add_req->ucPtrnSize);
6836
6837 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6838 if (ret)
6839 {
6840 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6841 goto fail;
6842 }
6843 add_req->ucPtrnId = pattern_id;
6844 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6845
6846 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6847 if (!HAL_STATUS_SUCCESS(status))
6848 {
6849 hddLog(LOGE,
6850 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6851 goto fail;
6852 }
6853
6854 EXIT();
6855 vos_mem_free(add_req);
6856 return 0;
6857
6858fail:
6859 vos_mem_free(add_req);
6860 return -EINVAL;
6861}
6862
6863/**
6864 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6865 * @adapter: adapter pointer
6866 * @hdd_ctx: hdd context
6867 * @tb: nl attributes
6868 *
6869 * This function reads the NL attributes and forms a DelTxPtrn message
6870 * posts it to SME.
6871 *
6872 */
6873static int
6874wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6875 struct nlattr **tb)
6876{
6877 struct sSirDelPeriodicTxPtrn *del_req;
6878 eHalStatus status;
6879 uint32_t request_id, ret;
6880 uint8_t pattern_id = 0;
6881
6882 /* Parse and fetch request Id */
6883 if (!tb[PARAM_REQUEST_ID])
6884 {
6885 hddLog(LOGE, FL("attr request id failed"));
6886 return -EINVAL;
6887 }
6888 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6889 if (request_id == 0)
6890 {
6891 hddLog(LOGE, FL("request_id cannot be zero"));
6892 return -EINVAL;
6893 }
6894
6895 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6896 if (ret)
6897 {
6898 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6899 return -EINVAL;
6900 }
6901
6902 del_req = vos_mem_malloc(sizeof(*del_req));
6903 if (!del_req)
6904 {
6905 hddLog(LOGE, FL("memory allocation failed"));
6906 return -ENOMEM;
6907 }
6908
6909 vos_mem_set(del_req, sizeof(*del_req), 0);
6910 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6911 VOS_MAC_ADDR_SIZE);
6912 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6913 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6914 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6915 request_id, pattern_id, del_req->ucPatternIdBitmap);
6916
6917 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6918 if (!HAL_STATUS_SUCCESS(status))
6919 {
6920 hddLog(LOGE,
6921 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6922 goto fail;
6923 }
6924
6925 EXIT();
6926 vos_mem_free(del_req);
6927 return 0;
6928
6929fail:
6930 vos_mem_free(del_req);
6931 return -EINVAL;
6932}
6933
6934
6935/**
6936 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6937 * @wiphy: Pointer to wireless phy
6938 * @wdev: Pointer to wireless device
6939 * @data: Pointer to data
6940 * @data_len: Data length
6941 *
6942 * Return: 0 on success, negative errno on failure
6943 */
6944static int
6945__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6946 struct wireless_dev *wdev,
6947 const void *data,
6948 int data_len)
6949{
6950 struct net_device *dev = wdev->netdev;
6951 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6952 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6953 struct nlattr *tb[PARAM_MAX + 1];
6954 uint8_t control;
6955 int ret;
6956 static const struct nla_policy policy[PARAM_MAX + 1] =
6957 {
6958 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6959 [PARAM_CONTROL] = { .type = NLA_U32 },
6960 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
6961 .len = VOS_MAC_ADDR_SIZE },
6962 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
6963 .len = VOS_MAC_ADDR_SIZE },
6964 [PARAM_PERIOD] = { .type = NLA_U32 },
6965 };
6966
6967 ENTER();
6968
6969 ret = wlan_hdd_validate_context(hdd_ctx);
6970 if (0 != ret)
6971 {
6972 hddLog(LOGE, FL("HDD context is not valid"));
6973 return ret;
6974 }
6975
6976 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
6977 {
6978 hddLog(LOGE,
6979 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
6980 return -ENOTSUPP;
6981 }
6982
6983 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
6984 {
6985 hddLog(LOGE, FL("Invalid ATTR"));
6986 return -EINVAL;
6987 }
6988
6989 if (!tb[PARAM_CONTROL])
6990 {
6991 hddLog(LOGE, FL("attr control failed"));
6992 return -EINVAL;
6993 }
6994 control = nla_get_u32(tb[PARAM_CONTROL]);
6995 hddLog(LOG1, FL("Control: %d"), control);
6996
6997 if (control == WLAN_START_OFFLOADED_PACKETS)
6998 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
6999 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7000 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7001 else
7002 {
7003 hddLog(LOGE, FL("Invalid control: %d"), control);
7004 return -EINVAL;
7005 }
7006}
7007
7008/*
7009 * done with short names for the global vendor params
7010 * used by __wlan_hdd_cfg80211_offloaded_packets()
7011 */
7012#undef PARAM_MAX
7013#undef PARAM_REQUEST_ID
7014#undef PARAM_CONTROL
7015#undef PARAM_IP_PACKET
7016#undef PARAM_SRC_MAC_ADDR
7017#undef PARAM_DST_MAC_ADDR
7018#undef PARAM_PERIOD
7019
7020/**
7021 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7022 * @wiphy: wiphy structure pointer
7023 * @wdev: Wireless device structure pointer
7024 * @data: Pointer to the data received
7025 * @data_len: Length of @data
7026 *
7027 * Return: 0 on success; errno on failure
7028 */
7029static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7030 struct wireless_dev *wdev,
7031 const void *data,
7032 int data_len)
7033{
7034 int ret = 0;
7035
7036 vos_ssr_protect(__func__);
7037 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7038 wdev, data, data_len);
7039 vos_ssr_unprotect(__func__);
7040
7041 return ret;
7042}
7043#endif
7044
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307045static const struct
7046nla_policy
7047qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7048 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7049};
7050
7051/**
7052 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7053 * get link properties like nss, rate flags and operating frequency for
7054 * the connection with the given peer.
7055 * @wiphy: WIPHY structure pointer
7056 * @wdev: Wireless device structure pointer
7057 * @data: Pointer to the data received
7058 * @data_len: Length of the data received
7059 *
7060 * This function return the above link properties on success.
7061 *
7062 * Return: 0 on success and errno on failure
7063 */
7064static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7065 struct wireless_dev *wdev,
7066 const void *data,
7067 int data_len)
7068{
7069 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7070 struct net_device *dev = wdev->netdev;
7071 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7072 hdd_station_ctx_t *hdd_sta_ctx;
7073 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7074 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7075 uint32_t sta_id;
7076 struct sk_buff *reply_skb;
7077 uint32_t rate_flags = 0;
7078 uint8_t nss;
7079 uint8_t final_rate_flags = 0;
7080 uint32_t freq;
7081 v_CONTEXT_t pVosContext = NULL;
7082 ptSapContext pSapCtx = NULL;
7083
7084 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7086 return -EINVAL;
7087 }
7088
7089 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7090 qca_wlan_vendor_attr_policy)) {
7091 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7092 return -EINVAL;
7093 }
7094
7095 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7096 hddLog(VOS_TRACE_LEVEL_ERROR,
7097 FL("Attribute peerMac not provided for mode=%d"),
7098 adapter->device_mode);
7099 return -EINVAL;
7100 }
7101
7102 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7103 sizeof(peer_mac));
7104 hddLog(VOS_TRACE_LEVEL_INFO,
7105 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7106 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7107
7108 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7109 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7110 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7111 if ((hdd_sta_ctx->conn_info.connState !=
7112 eConnectionState_Associated) ||
7113 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7114 VOS_MAC_ADDRESS_LEN)) {
7115 hddLog(VOS_TRACE_LEVEL_ERROR,
7116 FL("Not Associated to mac "MAC_ADDRESS_STR),
7117 MAC_ADDR_ARRAY(peer_mac));
7118 return -EINVAL;
7119 }
7120
7121 nss = 1; //pronto supports only one spatial stream
7122 freq = vos_chan_to_freq(
7123 hdd_sta_ctx->conn_info.operationChannel);
7124 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7125
7126 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7127 adapter->device_mode == WLAN_HDD_SOFTAP) {
7128
7129 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7130 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7131 if(pSapCtx == NULL){
7132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7133 FL("psapCtx is NULL"));
7134 return -ENOENT;
7135 }
7136
7137
7138 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7139 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7140 !vos_is_macaddr_broadcast(
7141 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7142 vos_mem_compare(
7143 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7144 peer_mac, VOS_MAC_ADDRESS_LEN))
7145 break;
7146 }
7147
7148 if (WLAN_MAX_STA_COUNT == sta_id) {
7149 hddLog(VOS_TRACE_LEVEL_ERROR,
7150 FL("No active peer with mac="MAC_ADDRESS_STR),
7151 MAC_ADDR_ARRAY(peer_mac));
7152 return -EINVAL;
7153 }
7154
7155 nss = 1; //pronto supports only one spatial stream
7156 freq = vos_chan_to_freq(
7157 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7158 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7159 } else {
7160 hddLog(VOS_TRACE_LEVEL_ERROR,
7161 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7162 MAC_ADDR_ARRAY(peer_mac));
7163 return -EINVAL;
7164 }
7165
7166 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7167 if (rate_flags & eHAL_TX_RATE_VHT80) {
7168 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7169 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7170 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7171 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7172 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7173 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7174 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7175 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7176 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7177 if (rate_flags & eHAL_TX_RATE_HT40)
7178 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7179 }
7180
7181 if (rate_flags & eHAL_TX_RATE_SGI) {
7182 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7183 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7184 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7185 }
7186 }
7187
7188 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7189 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7190
7191 if (NULL == reply_skb) {
7192 hddLog(VOS_TRACE_LEVEL_ERROR,
7193 FL("getLinkProperties: skb alloc failed"));
7194 return -EINVAL;
7195 }
7196
7197 if (nla_put_u8(reply_skb,
7198 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7199 nss) ||
7200 nla_put_u8(reply_skb,
7201 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7202 final_rate_flags) ||
7203 nla_put_u32(reply_skb,
7204 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7205 freq)) {
7206 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7207 kfree_skb(reply_skb);
7208 return -EINVAL;
7209 }
7210
7211 return cfg80211_vendor_cmd_reply(reply_skb);
7212}
7213
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307214#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7215#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7216#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7217#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307218#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7219 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307220
7221/**
7222 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7223 * vendor command
7224 *
7225 * @wiphy: wiphy device pointer
7226 * @wdev: wireless device pointer
7227 * @data: Vendor command data buffer
7228 * @data_len: Buffer length
7229 *
7230 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7231 *
7232 * Return: EOK or other error codes.
7233 */
7234
7235static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7236 struct wireless_dev *wdev,
7237 const void *data,
7238 int data_len)
7239{
7240 struct net_device *dev = wdev->netdev;
7241 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7242 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7243 hdd_station_ctx_t *pHddStaCtx;
7244 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7245 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307246 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307247 eHalStatus status;
7248 int ret_val;
7249 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7250 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7251 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307252 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7253 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7254 { .type = NLA_U32},
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307255 };
7256
7257 ENTER();
7258
7259 if (VOS_FTM_MODE == hdd_get_conparam()) {
7260 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7261 return -EINVAL;
7262 }
7263
7264 ret_val = wlan_hdd_validate_context(pHddCtx);
7265 if (ret_val) {
7266 return ret_val;
7267 }
7268
7269 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7270
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307271 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7272 hddLog(LOGE, FL("Invalid ATTR"));
7273 return -EINVAL;
7274 }
7275
7276 /* check the Wifi Capability */
7277 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7278 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7279 {
7280 hddLog(VOS_TRACE_LEVEL_ERROR,
7281 FL("WIFICONFIG not supported by Firmware"));
7282 return -EINVAL;
7283 }
7284
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307285 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7286 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7287 modifyRoamParamsReq.value =
7288 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7289
7290 if (eHAL_STATUS_SUCCESS !=
7291 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7292 {
7293 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7294 ret_val = -EINVAL;
7295 }
7296 return ret_val;
7297 }
7298
7299 /* Moved this down in order to provide provision to set beacon
7300 * miss penalty count irrespective of connection state.
7301 */
7302 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7303 hddLog(LOGE, FL("Not in Connected state!"));
7304 return -ENOTSUPP;
7305 }
7306
7307 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307308
7309 if (!pReq) {
7310 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7311 "%s: Not able to allocate memory for tSetWifiConfigParams",
7312 __func__);
7313 return eHAL_STATUS_E_MALLOC_FAILED;
7314 }
7315
7316 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7317
7318 pReq->sessionId = pAdapter->sessionId;
7319 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7320
7321 if (tb[PARAM_MODULATED_DTIM]) {
7322 pReq->paramValue = nla_get_u32(
7323 tb[PARAM_MODULATED_DTIM]);
7324 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7325 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307326 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307327 hdd_set_pwrparams(pHddCtx);
7328 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7329 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7330
7331 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7332 iw_full_power_cbfn, pAdapter,
7333 eSME_FULL_PWR_NEEDED_BY_HDD);
7334 }
7335 else
7336 {
7337 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7338 }
7339 }
7340
7341 if (tb[PARAM_STATS_AVG_FACTOR]) {
7342 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7343 pReq->paramValue = nla_get_u16(
7344 tb[PARAM_STATS_AVG_FACTOR]);
7345 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7346 pReq->paramType, pReq->paramValue);
7347 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7348
7349 if (eHAL_STATUS_SUCCESS != status)
7350 {
7351 vos_mem_free(pReq);
7352 pReq = NULL;
7353 ret_val = -EPERM;
7354 return ret_val;
7355 }
7356 }
7357
7358
7359 if (tb[PARAM_GUARD_TIME]) {
7360 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7361 pReq->paramValue = nla_get_u32(
7362 tb[PARAM_GUARD_TIME]);
7363 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7364 pReq->paramType, pReq->paramValue);
7365 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7366
7367 if (eHAL_STATUS_SUCCESS != status)
7368 {
7369 vos_mem_free(pReq);
7370 pReq = NULL;
7371 ret_val = -EPERM;
7372 return ret_val;
7373 }
7374
7375 }
7376
7377 EXIT();
7378 return ret_val;
7379}
7380
7381/**
7382 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7383 * vendor command
7384 *
7385 * @wiphy: wiphy device pointer
7386 * @wdev: wireless device pointer
7387 * @data: Vendor command data buffer
7388 * @data_len: Buffer length
7389 *
7390 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7391 *
7392 * Return: EOK or other error codes.
7393 */
7394static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7395 struct wireless_dev *wdev,
7396 const void *data,
7397 int data_len)
7398{
7399 int ret;
7400
7401 vos_ssr_protect(__func__);
7402 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7403 data, data_len);
7404 vos_ssr_unprotect(__func__);
7405
7406 return ret;
7407}
Sunil Duttc69bccb2014-05-26 21:30:20 +05307408const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7409{
Mukul Sharma2a271632014-10-13 14:59:01 +05307410 {
7411 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7412 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7413 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7414 WIPHY_VENDOR_CMD_NEED_NETDEV |
7415 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307416 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307417 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307418
7419 {
7420 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7421 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7422 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7423 WIPHY_VENDOR_CMD_NEED_NETDEV |
7424 WIPHY_VENDOR_CMD_NEED_RUNNING,
7425 .doit = wlan_hdd_cfg80211_nan_request
7426 },
7427
Sunil Duttc69bccb2014-05-26 21:30:20 +05307428#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7429 {
7430 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7431 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7432 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7433 WIPHY_VENDOR_CMD_NEED_NETDEV |
7434 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307435 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307436 },
7437
7438 {
7439 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7440 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7441 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7442 WIPHY_VENDOR_CMD_NEED_NETDEV |
7443 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307444 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307445 },
7446
7447 {
7448 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7449 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7450 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7451 WIPHY_VENDOR_CMD_NEED_NETDEV |
7452 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307453 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307454 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307455#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307456#ifdef WLAN_FEATURE_EXTSCAN
7457 {
7458 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7459 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7460 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7461 WIPHY_VENDOR_CMD_NEED_NETDEV |
7462 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307463 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307464 },
7465 {
7466 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7467 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7468 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7469 WIPHY_VENDOR_CMD_NEED_NETDEV |
7470 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307471 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307472 },
7473 {
7474 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7475 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7476 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7477 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307478 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307479 },
7480 {
7481 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7482 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7483 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7484 WIPHY_VENDOR_CMD_NEED_NETDEV |
7485 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307486 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307487 },
7488 {
7489 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7490 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7491 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7492 WIPHY_VENDOR_CMD_NEED_NETDEV |
7493 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307494 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307495 },
7496 {
7497 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7498 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7499 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7500 WIPHY_VENDOR_CMD_NEED_NETDEV |
7501 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307502 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307503 },
7504 {
7505 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7506 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7507 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7508 WIPHY_VENDOR_CMD_NEED_NETDEV |
7509 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307510 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307511 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307512 {
7513 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7514 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7515 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7516 WIPHY_VENDOR_CMD_NEED_NETDEV |
7517 WIPHY_VENDOR_CMD_NEED_RUNNING,
7518 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7519 },
7520 {
7521 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7522 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7523 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7524 WIPHY_VENDOR_CMD_NEED_NETDEV |
7525 WIPHY_VENDOR_CMD_NEED_RUNNING,
7526 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7527 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307528#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307529/*EXT TDLS*/
7530 {
7531 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7532 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7533 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7534 WIPHY_VENDOR_CMD_NEED_NETDEV |
7535 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307536 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307537 },
7538 {
7539 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7540 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7541 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7542 WIPHY_VENDOR_CMD_NEED_NETDEV |
7543 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307544 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307545 },
7546 {
7547 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7548 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7549 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7550 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307551 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307552 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307553 {
7554 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7555 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7556 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7557 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307558 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307559 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307560 {
7561 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7562 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7563 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7564 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307565 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307566 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307567 {
7568 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7569 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7570 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7571 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307572 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307573 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307574 {
7575 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7576 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7577 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7578 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307579 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307580 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307581 {
7582 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307583 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7584 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7585 WIPHY_VENDOR_CMD_NEED_NETDEV |
7586 WIPHY_VENDOR_CMD_NEED_RUNNING,
7587 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7588 },
7589 {
7590 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307591 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7592 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7593 WIPHY_VENDOR_CMD_NEED_NETDEV |
7594 WIPHY_VENDOR_CMD_NEED_RUNNING,
7595 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307596 },
7597 {
7598 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7599 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7600 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7601 WIPHY_VENDOR_CMD_NEED_NETDEV,
7602 .doit = wlan_hdd_cfg80211_wifi_logger_start
7603 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307604 {
7605 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7606 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7607 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7608 WIPHY_VENDOR_CMD_NEED_NETDEV|
7609 WIPHY_VENDOR_CMD_NEED_RUNNING,
7610 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307611 },
7612 {
7613 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7614 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7615 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7616 WIPHY_VENDOR_CMD_NEED_NETDEV |
7617 WIPHY_VENDOR_CMD_NEED_RUNNING,
7618 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307619 },
7620 {
7621 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7622 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7623 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7624 WIPHY_VENDOR_CMD_NEED_NETDEV |
7625 WIPHY_VENDOR_CMD_NEED_RUNNING,
7626 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307627 },
7628#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7629 {
7630 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7631 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7632 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7633 WIPHY_VENDOR_CMD_NEED_NETDEV |
7634 WIPHY_VENDOR_CMD_NEED_RUNNING,
7635 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307636 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307637#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307638 {
7639 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7640 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7641 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7642 WIPHY_VENDOR_CMD_NEED_NETDEV |
7643 WIPHY_VENDOR_CMD_NEED_RUNNING,
7644 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307645 },
7646 {
7647 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7648 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7649 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7650 WIPHY_VENDOR_CMD_NEED_NETDEV |
7651 WIPHY_VENDOR_CMD_NEED_RUNNING,
7652 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307653 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05307654};
7655
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007656/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307657static const
7658struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007659{
7660#ifdef FEATURE_WLAN_CH_AVOID
7661 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307662 .vendor_id = QCA_NL80211_VENDOR_ID,
7663 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007664 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307665#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7666#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7667 {
7668 /* Index = 1*/
7669 .vendor_id = QCA_NL80211_VENDOR_ID,
7670 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7671 },
7672 {
7673 /* Index = 2*/
7674 .vendor_id = QCA_NL80211_VENDOR_ID,
7675 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7676 },
7677 {
7678 /* Index = 3*/
7679 .vendor_id = QCA_NL80211_VENDOR_ID,
7680 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7681 },
7682 {
7683 /* Index = 4*/
7684 .vendor_id = QCA_NL80211_VENDOR_ID,
7685 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7686 },
7687 {
7688 /* Index = 5*/
7689 .vendor_id = QCA_NL80211_VENDOR_ID,
7690 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7691 },
7692 {
7693 /* Index = 6*/
7694 .vendor_id = QCA_NL80211_VENDOR_ID,
7695 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7696 },
7697#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307698#ifdef WLAN_FEATURE_EXTSCAN
7699 {
7700 .vendor_id = QCA_NL80211_VENDOR_ID,
7701 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7702 },
7703 {
7704 .vendor_id = QCA_NL80211_VENDOR_ID,
7705 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7706 },
7707 {
7708 .vendor_id = QCA_NL80211_VENDOR_ID,
7709 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7710 },
7711 {
7712 .vendor_id = QCA_NL80211_VENDOR_ID,
7713 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7714 },
7715 {
7716 .vendor_id = QCA_NL80211_VENDOR_ID,
7717 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7718 },
7719 {
7720 .vendor_id = QCA_NL80211_VENDOR_ID,
7721 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7722 },
7723 {
7724 .vendor_id = QCA_NL80211_VENDOR_ID,
7725 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7726 },
7727 {
7728 .vendor_id = QCA_NL80211_VENDOR_ID,
7729 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7730 },
7731 {
7732 .vendor_id = QCA_NL80211_VENDOR_ID,
7733 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7734 },
7735 {
7736 .vendor_id = QCA_NL80211_VENDOR_ID,
7737 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7738 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307739 {
7740 .vendor_id = QCA_NL80211_VENDOR_ID,
7741 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7742 },
7743 {
7744 .vendor_id = QCA_NL80211_VENDOR_ID,
7745 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7746 },
7747 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7748 .vendor_id = QCA_NL80211_VENDOR_ID,
7749 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7750 },
7751 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7752 .vendor_id = QCA_NL80211_VENDOR_ID,
7753 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7754 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307755#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307756/*EXT TDLS*/
7757 {
7758 .vendor_id = QCA_NL80211_VENDOR_ID,
7759 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7760 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307761 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7762 .vendor_id = QCA_NL80211_VENDOR_ID,
7763 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7764 },
7765
Srinivas Dasari030bad32015-02-18 23:23:54 +05307766
7767 {
7768 .vendor_id = QCA_NL80211_VENDOR_ID,
7769 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7770 },
7771
Sushant Kaushik084f6592015-09-10 13:11:56 +05307772 {
7773 .vendor_id = QCA_NL80211_VENDOR_ID,
7774 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307775 },
7776 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7777 .vendor_id = QCA_NL80211_VENDOR_ID,
7778 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7779 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05307780 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
7781 .vendor_id = QCA_NL80211_VENDOR_ID,
7782 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
7783 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307784
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007785};
7786
Jeff Johnson295189b2012-06-20 16:38:30 -07007787/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307788 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307789 * This function is called by hdd_wlan_startup()
7790 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307791 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007792 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307793struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007794{
7795 struct wiphy *wiphy;
7796 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307797 /*
7798 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007799 */
7800 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7801
7802 if (!wiphy)
7803 {
7804 /* Print error and jump into err label and free the memory */
7805 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7806 return NULL;
7807 }
7808
Sunil Duttc69bccb2014-05-26 21:30:20 +05307809
Jeff Johnson295189b2012-06-20 16:38:30 -07007810 return wiphy;
7811}
7812
7813/*
7814 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307815 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007816 * private ioctl to change the band value
7817 */
7818int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7819{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307820 int i, j;
7821 eNVChannelEnabledType channelEnabledState;
7822
Jeff Johnsone7245742012-09-05 17:12:55 -07007823 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307824
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307825 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007826 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307827
7828 if (NULL == wiphy->bands[i])
7829 {
7830 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7831 __func__, i);
7832 continue;
7833 }
7834
7835 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7836 {
7837 struct ieee80211_supported_band *band = wiphy->bands[i];
7838
7839 channelEnabledState = vos_nv_getChannelEnabledState(
7840 band->channels[j].hw_value);
7841
7842 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7843 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307844 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307845 continue;
7846 }
7847 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7848 {
7849 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7850 continue;
7851 }
7852
7853 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7854 NV_CHANNEL_INVALID == channelEnabledState)
7855 {
7856 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7857 }
7858 else if (NV_CHANNEL_DFS == channelEnabledState)
7859 {
7860 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7861 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7862 }
7863 else
7864 {
7865 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7866 |IEEE80211_CHAN_RADAR);
7867 }
7868 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007869 }
7870 return 0;
7871}
7872/*
7873 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307874 * This function is called by hdd_wlan_startup()
7875 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007876 * This function is used to initialize and register wiphy structure.
7877 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307878int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007879 struct wiphy *wiphy,
7880 hdd_config_t *pCfg
7881 )
7882{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307883 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307884 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7885
Jeff Johnsone7245742012-09-05 17:12:55 -07007886 ENTER();
7887
Jeff Johnson295189b2012-06-20 16:38:30 -07007888 /* Now bind the underlying wlan device with wiphy */
7889 set_wiphy_dev(wiphy, dev);
7890
7891 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007892
Kiet Lam6c583332013-10-14 05:37:09 +05307893#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007894 /* the flag for the other case would be initialzed in
7895 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07007896 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307897#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007898
Amar Singhalfddc28c2013-09-05 13:03:40 -07007899 /* This will disable updating of NL channels from passive to
7900 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307901#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7902 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7903#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007904 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307905#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007906
Amar Singhala49cbc52013-10-08 18:37:44 -07007907
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007908#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007909 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7910 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7911 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007912 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307913#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7914 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
7915#else
7916 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7917#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007918#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007919
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007920#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007921 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007922#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007923 || pCfg->isFastRoamIniFeatureEnabled
7924#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007925#ifdef FEATURE_WLAN_ESE
7926 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007927#endif
7928 )
7929 {
7930 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7931 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007932#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007933#ifdef FEATURE_WLAN_TDLS
7934 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7935 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7936#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307937#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307938 if (pCfg->configPNOScanSupport)
7939 {
7940 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7941 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7942 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7943 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7944 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307945#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007946
Abhishek Singh10d85972015-04-17 10:27:23 +05307947#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7948 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7949#endif
7950
Amar Singhalfddc28c2013-09-05 13:03:40 -07007951#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007952 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
7953 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07007954 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007955 driver need to determine what to do with both
7956 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07007957
7958 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07007959#else
7960 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007961#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007962
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307963 wiphy->max_scan_ssids = MAX_SCAN_SSID;
7964
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05307965 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07007966
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307967 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
7968
Jeff Johnson295189b2012-06-20 16:38:30 -07007969 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05307970 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
7971 | BIT(NL80211_IFTYPE_ADHOC)
7972 | BIT(NL80211_IFTYPE_P2P_CLIENT)
7973 | BIT(NL80211_IFTYPE_P2P_GO)
7974 | BIT(NL80211_IFTYPE_AP);
7975
7976 if (VOS_MONITOR_MODE == hdd_get_conparam())
7977 {
7978 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
7979 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007980
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307981 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007982 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307983#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7984 if( pCfg->enableMCC )
7985 {
7986 /* Currently, supports up to two channels */
7987 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007988
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307989 if( !pCfg->allowMCCGODiffBI )
7990 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007991
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307992 }
7993 wiphy->iface_combinations = &wlan_hdd_iface_combination;
7994 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007995#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307996 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007997
Jeff Johnson295189b2012-06-20 16:38:30 -07007998 /* Before registering we need to update the ht capabilitied based
7999 * on ini values*/
8000 if( !pCfg->ShortGI20MhzEnable )
8001 {
8002 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8003 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008004 }
8005
8006 if( !pCfg->ShortGI40MhzEnable )
8007 {
8008 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8009 }
8010
8011 if( !pCfg->nChannelBondingMode5GHz )
8012 {
8013 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8014 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308015 /*
8016 * In case of static linked driver at the time of driver unload,
8017 * module exit doesn't happens. Module cleanup helps in cleaning
8018 * of static memory.
8019 * If driver load happens statically, at the time of driver unload,
8020 * wiphy flags don't get reset because of static memory.
8021 * It's better not to store channel in static memory.
8022 */
8023 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8024 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8025 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8026 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8027 {
8028 hddLog(VOS_TRACE_LEVEL_ERROR,
8029 FL("Not enough memory to allocate channels"));
8030 return -ENOMEM;
8031 }
8032 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8033 &hdd_channels_2_4_GHZ[0],
8034 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008035
Agrawal Ashish97dec502015-11-26 20:20:58 +05308036 if (true == hdd_is_5g_supported(pHddCtx))
8037 {
8038 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8039 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8040 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8041 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8042 {
8043 hddLog(VOS_TRACE_LEVEL_ERROR,
8044 FL("Not enough memory to allocate channels"));
8045 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8046 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8047 return -ENOMEM;
8048 }
8049 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8050 &hdd_channels_5_GHZ[0],
8051 sizeof(hdd_channels_5_GHZ));
8052 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308053
8054 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8055 {
8056
8057 if (NULL == wiphy->bands[i])
8058 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308059 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308060 __func__, i);
8061 continue;
8062 }
8063
8064 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8065 {
8066 struct ieee80211_supported_band *band = wiphy->bands[i];
8067
8068 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8069 {
8070 // Enable social channels for P2P
8071 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8072 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8073 else
8074 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8075 continue;
8076 }
8077 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8078 {
8079 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8080 continue;
8081 }
8082 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008083 }
8084 /*Initialise the supported cipher suite details*/
8085 wiphy->cipher_suites = hdd_cipher_suites;
8086 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8087
8088 /*signal strength in mBm (100*dBm) */
8089 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8090
8091#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308092 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008093#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008094
Sunil Duttc69bccb2014-05-26 21:30:20 +05308095 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8096 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008097 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8098 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8099
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308100 EXIT();
8101 return 0;
8102}
8103
8104/* In this function we are registering wiphy. */
8105int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8106{
8107 ENTER();
8108 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008109 if (0 > wiphy_register(wiphy))
8110 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308111 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008112 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8113 return -EIO;
8114 }
8115
8116 EXIT();
8117 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308118}
Jeff Johnson295189b2012-06-20 16:38:30 -07008119
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308120/* In this function we are updating channel list when,
8121 regulatory domain is FCC and country code is US.
8122 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8123 As per FCC smart phone is not a indoor device.
8124 GO should not opeate on indoor channels */
8125void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8126{
8127 int j;
8128 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8129 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8130 //Default counrtycode from NV at the time of wiphy initialization.
8131 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8132 &defaultCountryCode[0]))
8133 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008134 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308135 }
8136 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8137 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308138 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8139 {
8140 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8141 return;
8142 }
8143 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8144 {
8145 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8146 // Mark UNII -1 band channel as passive
8147 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8148 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8149 }
8150 }
8151}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308152/* This function registers for all frame which supplicant is interested in */
8153void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008154{
Jeff Johnson295189b2012-06-20 16:38:30 -07008155 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8156 /* Register for all P2P action, public action etc frames */
8157 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008158 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308159 /* Register frame indication call back */
8160 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008161 /* Right now we are registering these frame when driver is getting
8162 initialized. Once we will move to 2.6.37 kernel, in which we have
8163 frame register ops, we will move this code as a part of that */
8164 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308165 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008166 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8167
8168 /* GAS Initial Response */
8169 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8170 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308171
Jeff Johnson295189b2012-06-20 16:38:30 -07008172 /* GAS Comeback Request */
8173 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8174 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8175
8176 /* GAS Comeback Response */
8177 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8178 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8179
8180 /* P2P Public Action */
8181 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308182 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008183 P2P_PUBLIC_ACTION_FRAME_SIZE );
8184
8185 /* P2P Action */
8186 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8187 (v_U8_t*)P2P_ACTION_FRAME,
8188 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008189
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308190 /* WNM BSS Transition Request frame */
8191 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8192 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8193 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008194
8195 /* WNM-Notification */
8196 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8197 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8198 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008199}
8200
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308201void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008202{
Jeff Johnson295189b2012-06-20 16:38:30 -07008203 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8204 /* Register for all P2P action, public action etc frames */
8205 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8206
Jeff Johnsone7245742012-09-05 17:12:55 -07008207 ENTER();
8208
Jeff Johnson295189b2012-06-20 16:38:30 -07008209 /* Right now we are registering these frame when driver is getting
8210 initialized. Once we will move to 2.6.37 kernel, in which we have
8211 frame register ops, we will move this code as a part of that */
8212 /* GAS Initial Request */
8213
8214 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8215 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8216
8217 /* GAS Initial Response */
8218 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8219 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308220
Jeff Johnson295189b2012-06-20 16:38:30 -07008221 /* GAS Comeback Request */
8222 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8223 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8224
8225 /* GAS Comeback Response */
8226 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8227 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8228
8229 /* P2P Public Action */
8230 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308231 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008232 P2P_PUBLIC_ACTION_FRAME_SIZE );
8233
8234 /* P2P Action */
8235 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8236 (v_U8_t*)P2P_ACTION_FRAME,
8237 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008238 /* WNM-Notification */
8239 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8240 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8241 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008242}
8243
8244#ifdef FEATURE_WLAN_WAPI
8245void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308246 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008247{
8248 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8249 tCsrRoamSetKey setKey;
8250 v_BOOL_t isConnected = TRUE;
8251 int status = 0;
8252 v_U32_t roamId= 0xFF;
8253 tANI_U8 *pKeyPtr = NULL;
8254 int n = 0;
8255
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308256 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8257 __func__, hdd_device_modetoString(pAdapter->device_mode),
8258 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008259
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308260 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008261 setKey.keyId = key_index; // Store Key ID
8262 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8263 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8264 setKey.paeRole = 0 ; // the PAE role
8265 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8266 {
8267 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8268 }
8269 else
8270 {
8271 isConnected = hdd_connIsConnected(pHddStaCtx);
8272 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8273 }
8274 setKey.keyLength = key_Len;
8275 pKeyPtr = setKey.Key;
8276 memcpy( pKeyPtr, key, key_Len);
8277
Arif Hussain6d2a3322013-11-17 19:50:10 -08008278 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008279 __func__, key_Len);
8280 for (n = 0 ; n < key_Len; n++)
8281 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8282 __func__,n,setKey.Key[n]);
8283
8284 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8285 if ( isConnected )
8286 {
8287 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8288 pAdapter->sessionId, &setKey, &roamId );
8289 }
8290 if ( status != 0 )
8291 {
8292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8293 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8294 __LINE__, status );
8295 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8296 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308297 /* Need to clear any trace of key value in the memory.
8298 * Thus zero out the memory even though it is local
8299 * variable.
8300 */
8301 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008302}
8303#endif /* FEATURE_WLAN_WAPI*/
8304
8305#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308306int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008307 beacon_data_t **ppBeacon,
8308 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008309#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308310int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008311 beacon_data_t **ppBeacon,
8312 struct cfg80211_beacon_data *params,
8313 int dtim_period)
8314#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308315{
Jeff Johnson295189b2012-06-20 16:38:30 -07008316 int size;
8317 beacon_data_t *beacon = NULL;
8318 beacon_data_t *old = NULL;
8319 int head_len,tail_len;
8320
Jeff Johnsone7245742012-09-05 17:12:55 -07008321 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008322 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308323 {
8324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8325 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008326 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308327 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008328
8329 old = pAdapter->sessionCtx.ap.beacon;
8330
8331 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308332 {
8333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8334 FL("session(%d) old and new heads points to NULL"),
8335 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008336 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308337 }
8338
8339 if (params->tail && !params->tail_len)
8340 {
8341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8342 FL("tail_len is zero but tail is not NULL"));
8343 return -EINVAL;
8344 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008345
Jeff Johnson295189b2012-06-20 16:38:30 -07008346#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8347 /* Kernel 3.0 is not updating dtim_period for set beacon */
8348 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308349 {
8350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8351 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008352 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308353 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008354#endif
8355
8356 if(params->head)
8357 head_len = params->head_len;
8358 else
8359 head_len = old->head_len;
8360
8361 if(params->tail || !old)
8362 tail_len = params->tail_len;
8363 else
8364 tail_len = old->tail_len;
8365
8366 size = sizeof(beacon_data_t) + head_len + tail_len;
8367
8368 beacon = kzalloc(size, GFP_KERNEL);
8369
8370 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308371 {
8372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8373 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008374 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308375 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008376
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008377#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008378 if(params->dtim_period || !old )
8379 beacon->dtim_period = params->dtim_period;
8380 else
8381 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008382#else
8383 if(dtim_period || !old )
8384 beacon->dtim_period = dtim_period;
8385 else
8386 beacon->dtim_period = old->dtim_period;
8387#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308388
Jeff Johnson295189b2012-06-20 16:38:30 -07008389 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8390 beacon->tail = beacon->head + head_len;
8391 beacon->head_len = head_len;
8392 beacon->tail_len = tail_len;
8393
8394 if(params->head) {
8395 memcpy (beacon->head,params->head,beacon->head_len);
8396 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308397 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07008398 if(old)
8399 memcpy (beacon->head,old->head,beacon->head_len);
8400 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308401
Jeff Johnson295189b2012-06-20 16:38:30 -07008402 if(params->tail) {
8403 memcpy (beacon->tail,params->tail,beacon->tail_len);
8404 }
8405 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308406 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07008407 memcpy (beacon->tail,old->tail,beacon->tail_len);
8408 }
8409
8410 *ppBeacon = beacon;
8411
8412 kfree(old);
8413
8414 return 0;
8415
8416}
Jeff Johnson295189b2012-06-20 16:38:30 -07008417
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308418v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8419#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8420 const v_U8_t *pIes,
8421#else
8422 v_U8_t *pIes,
8423#endif
8424 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008425{
8426 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308427 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008428 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308429
Jeff Johnson295189b2012-06-20 16:38:30 -07008430 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308431 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008432 elem_id = ptr[0];
8433 elem_len = ptr[1];
8434 left -= 2;
8435 if(elem_len > left)
8436 {
8437 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008438 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008439 eid,elem_len,left);
8440 return NULL;
8441 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308442 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 {
8444 return ptr;
8445 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308446
Jeff Johnson295189b2012-06-20 16:38:30 -07008447 left -= elem_len;
8448 ptr += (elem_len + 2);
8449 }
8450 return NULL;
8451}
8452
Jeff Johnson295189b2012-06-20 16:38:30 -07008453/* Check if rate is 11g rate or not */
8454static int wlan_hdd_rate_is_11g(u8 rate)
8455{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008456 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008457 u8 i;
8458 for (i = 0; i < 8; i++)
8459 {
8460 if(rate == gRateArray[i])
8461 return TRUE;
8462 }
8463 return FALSE;
8464}
8465
8466/* Check for 11g rate and set proper 11g only mode */
8467static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8468 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8469{
8470 u8 i, num_rates = pIe[0];
8471
8472 pIe += 1;
8473 for ( i = 0; i < num_rates; i++)
8474 {
8475 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8476 {
8477 /* If rate set have 11g rate than change the mode to 11G */
8478 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8479 if (pIe[i] & BASIC_RATE_MASK)
8480 {
8481 /* If we have 11g rate as basic rate, it means mode
8482 is 11g only mode.
8483 */
8484 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8485 *pCheckRatesfor11g = FALSE;
8486 }
8487 }
8488 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8489 {
8490 *require_ht = TRUE;
8491 }
8492 }
8493 return;
8494}
8495
8496static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8497{
8498 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8499 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8500 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8501 u8 checkRatesfor11g = TRUE;
8502 u8 require_ht = FALSE;
8503 u8 *pIe=NULL;
8504
8505 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8506
8507 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8508 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8509 if (pIe != NULL)
8510 {
8511 pIe += 1;
8512 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8513 &pConfig->SapHw_mode);
8514 }
8515
8516 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8517 WLAN_EID_EXT_SUPP_RATES);
8518 if (pIe != NULL)
8519 {
8520
8521 pIe += 1;
8522 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8523 &pConfig->SapHw_mode);
8524 }
8525
8526 if( pConfig->channel > 14 )
8527 {
8528 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8529 }
8530
8531 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8532 WLAN_EID_HT_CAPABILITY);
8533
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308534 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008535 {
8536 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8537 if(require_ht)
8538 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8539 }
8540}
8541
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308542static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8543 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8544{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008545 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308546 v_U8_t *pIe = NULL;
8547 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8548
8549 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8550 pBeacon->tail, pBeacon->tail_len);
8551
8552 if (pIe)
8553 {
8554 ielen = pIe[1] + 2;
8555 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8556 {
8557 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8558 }
8559 else
8560 {
8561 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8562 return -EINVAL;
8563 }
8564 *total_ielen += ielen;
8565 }
8566 return 0;
8567}
8568
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008569static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8570 v_U8_t *genie, v_U8_t *total_ielen)
8571{
8572 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8573 int left = pBeacon->tail_len;
8574 v_U8_t *ptr = pBeacon->tail;
8575 v_U8_t elem_id, elem_len;
8576 v_U16_t ielen = 0;
8577
8578 if ( NULL == ptr || 0 == left )
8579 return;
8580
8581 while (left >= 2)
8582 {
8583 elem_id = ptr[0];
8584 elem_len = ptr[1];
8585 left -= 2;
8586 if (elem_len > left)
8587 {
8588 hddLog( VOS_TRACE_LEVEL_ERROR,
8589 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8590 elem_id, elem_len, left);
8591 return;
8592 }
8593 if (IE_EID_VENDOR == elem_id)
8594 {
8595 /* skipping the VSIE's which we don't want to include or
8596 * it will be included by existing code
8597 */
8598 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8599#ifdef WLAN_FEATURE_WFD
8600 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8601#endif
8602 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8603 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8604 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8605 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8606 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8607 {
8608 ielen = ptr[1] + 2;
8609 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8610 {
8611 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8612 *total_ielen += ielen;
8613 }
8614 else
8615 {
8616 hddLog( VOS_TRACE_LEVEL_ERROR,
8617 "IE Length is too big "
8618 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8619 elem_id, elem_len, *total_ielen);
8620 }
8621 }
8622 }
8623
8624 left -= elem_len;
8625 ptr += (elem_len + 2);
8626 }
8627 return;
8628}
8629
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008630#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008631static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8632 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008633#else
8634static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8635 struct cfg80211_beacon_data *params)
8636#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008637{
8638 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308639 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008640 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008641 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008642
8643 genie = vos_mem_malloc(MAX_GENIE_LEN);
8644
8645 if(genie == NULL) {
8646
8647 return -ENOMEM;
8648 }
8649
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308650 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8651 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008652 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308653 hddLog(LOGE,
8654 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308655 ret = -EINVAL;
8656 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008657 }
8658
8659#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308660 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8661 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8662 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308663 hddLog(LOGE,
8664 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308665 ret = -EINVAL;
8666 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008667 }
8668#endif
8669
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308670 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8671 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008672 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308673 hddLog(LOGE,
8674 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308675 ret = -EINVAL;
8676 goto done;
8677 }
8678
8679 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8680 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008681 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008682 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008683
8684 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8685 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8686 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8687 {
8688 hddLog(LOGE,
8689 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008690 ret = -EINVAL;
8691 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008692 }
8693
8694 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8695 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8696 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8697 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8698 ==eHAL_STATUS_FAILURE)
8699 {
8700 hddLog(LOGE,
8701 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008702 ret = -EINVAL;
8703 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008704 }
8705
8706 // Added for ProResp IE
8707 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
8708 {
8709 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
8710 u8 probe_rsp_ie_len[3] = {0};
8711 u8 counter = 0;
8712 /* Check Probe Resp Length if it is greater then 255 then Store
8713 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8714 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8715 Store More then 255 bytes into One Variable.
8716 */
8717 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8718 {
8719 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8720 {
8721 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8722 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8723 }
8724 else
8725 {
8726 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8727 rem_probe_resp_ie_len = 0;
8728 }
8729 }
8730
8731 rem_probe_resp_ie_len = 0;
8732
8733 if (probe_rsp_ie_len[0] > 0)
8734 {
8735 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8736 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
8737 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8738 probe_rsp_ie_len[0], NULL,
8739 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8740 {
8741 hddLog(LOGE,
8742 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008743 ret = -EINVAL;
8744 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008745 }
8746 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8747 }
8748
8749 if (probe_rsp_ie_len[1] > 0)
8750 {
8751 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8752 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
8753 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8754 probe_rsp_ie_len[1], NULL,
8755 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8756 {
8757 hddLog(LOGE,
8758 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008759 ret = -EINVAL;
8760 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008761 }
8762 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8763 }
8764
8765 if (probe_rsp_ie_len[2] > 0)
8766 {
8767 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8768 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
8769 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8770 probe_rsp_ie_len[2], NULL,
8771 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8772 {
8773 hddLog(LOGE,
8774 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008775 ret = -EINVAL;
8776 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008777 }
8778 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8779 }
8780
8781 if (probe_rsp_ie_len[1] == 0 )
8782 {
8783 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8784 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8785 eANI_BOOLEAN_FALSE) )
8786 {
8787 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008788 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 }
8790 }
8791
8792 if (probe_rsp_ie_len[2] == 0 )
8793 {
8794 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8795 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8796 eANI_BOOLEAN_FALSE) )
8797 {
8798 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008799 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008800 }
8801 }
8802
8803 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8804 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8805 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8806 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8807 == eHAL_STATUS_FAILURE)
8808 {
8809 hddLog(LOGE,
8810 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008811 ret = -EINVAL;
8812 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008813 }
8814 }
8815 else
8816 {
8817 // Reset WNI_CFG_PROBE_RSP Flags
8818 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8819
8820 hddLog(VOS_TRACE_LEVEL_INFO,
8821 "%s: No Probe Response IE received in set beacon",
8822 __func__);
8823 }
8824
8825 // Added for AssocResp IE
8826 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
8827 {
8828 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8829 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
8830 params->assocresp_ies_len, NULL,
8831 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8832 {
8833 hddLog(LOGE,
8834 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008835 ret = -EINVAL;
8836 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008837 }
8838
8839 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8840 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8841 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8842 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8843 == eHAL_STATUS_FAILURE)
8844 {
8845 hddLog(LOGE,
8846 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008847 ret = -EINVAL;
8848 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008849 }
8850 }
8851 else
8852 {
8853 hddLog(VOS_TRACE_LEVEL_INFO,
8854 "%s: No Assoc Response IE received in set beacon",
8855 __func__);
8856
8857 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8858 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8859 eANI_BOOLEAN_FALSE) )
8860 {
8861 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008862 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008863 }
8864 }
8865
Jeff Johnsone7245742012-09-05 17:12:55 -07008866done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008867 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308868 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008869}
Jeff Johnson295189b2012-06-20 16:38:30 -07008870
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308871/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008872 * FUNCTION: wlan_hdd_validate_operation_channel
8873 * called by wlan_hdd_cfg80211_start_bss() and
8874 * wlan_hdd_cfg80211_set_channel()
8875 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308876 * channel list.
8877 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008878VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008879{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308880
Jeff Johnson295189b2012-06-20 16:38:30 -07008881 v_U32_t num_ch = 0;
8882 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8883 u32 indx = 0;
8884 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308885 v_U8_t fValidChannel = FALSE, count = 0;
8886 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308887
Jeff Johnson295189b2012-06-20 16:38:30 -07008888 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8889
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308890 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008891 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308892 /* Validate the channel */
8893 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008894 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308895 if ( channel == rfChannels[count].channelNum )
8896 {
8897 fValidChannel = TRUE;
8898 break;
8899 }
8900 }
8901 if (fValidChannel != TRUE)
8902 {
8903 hddLog(VOS_TRACE_LEVEL_ERROR,
8904 "%s: Invalid Channel [%d]", __func__, channel);
8905 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008906 }
8907 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308908 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008909 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308910 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8911 valid_ch, &num_ch))
8912 {
8913 hddLog(VOS_TRACE_LEVEL_ERROR,
8914 "%s: failed to get valid channel list", __func__);
8915 return VOS_STATUS_E_FAILURE;
8916 }
8917 for (indx = 0; indx < num_ch; indx++)
8918 {
8919 if (channel == valid_ch[indx])
8920 {
8921 break;
8922 }
8923 }
8924
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308925 if (indx >= num_ch)
8926 {
8927 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8928 {
8929 eCsrBand band;
8930 unsigned int freq;
8931
8932 sme_GetFreqBand(hHal, &band);
8933
8934 if (eCSR_BAND_5G == band)
8935 {
8936#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8937 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8938 {
8939 freq = ieee80211_channel_to_frequency(channel,
8940 IEEE80211_BAND_2GHZ);
8941 }
8942 else
8943 {
8944 freq = ieee80211_channel_to_frequency(channel,
8945 IEEE80211_BAND_5GHZ);
8946 }
8947#else
8948 freq = ieee80211_channel_to_frequency(channel);
8949#endif
8950 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
8951 return VOS_STATUS_SUCCESS;
8952 }
8953 }
8954
8955 hddLog(VOS_TRACE_LEVEL_ERROR,
8956 "%s: Invalid Channel [%d]", __func__, channel);
8957 return VOS_STATUS_E_FAILURE;
8958 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008959 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308960
Jeff Johnson295189b2012-06-20 16:38:30 -07008961 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308962
Jeff Johnson295189b2012-06-20 16:38:30 -07008963}
8964
Viral Modi3a32cc52013-02-08 11:14:52 -08008965/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308966 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08008967 * This function is used to set the channel number
8968 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308969static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08008970 struct ieee80211_channel *chan,
8971 enum nl80211_channel_type channel_type
8972 )
8973{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308974 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08008975 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07008976 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08008977 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308978 hdd_context_t *pHddCtx;
8979 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008980
8981 ENTER();
8982
8983 if( NULL == dev )
8984 {
8985 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008986 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08008987 return -ENODEV;
8988 }
8989 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308990
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308991 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8992 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
8993 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08008994 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308995 "%s: device_mode = %s (%d) freq = %d", __func__,
8996 hdd_device_modetoString(pAdapter->device_mode),
8997 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308998
8999 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9000 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309001 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009002 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309003 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009004 }
9005
9006 /*
9007 * Do freq to chan conversion
9008 * TODO: for 11a
9009 */
9010
9011 channel = ieee80211_frequency_to_channel(freq);
9012
9013 /* Check freq range */
9014 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9015 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9016 {
9017 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009018 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009019 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9020 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9021 return -EINVAL;
9022 }
9023
9024 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9025
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309026 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9027 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009028 {
9029 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9030 {
9031 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009032 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009033 return -EINVAL;
9034 }
9035 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9036 "%s: set channel to [%d] for device mode =%d",
9037 __func__, channel,pAdapter->device_mode);
9038 }
9039 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009040 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009041 )
9042 {
9043 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9044 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9045 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9046
9047 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9048 {
9049 /* Link is up then return cant set channel*/
9050 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009051 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009052 return -EINVAL;
9053 }
9054
9055 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9056 pHddStaCtx->conn_info.operationChannel = channel;
9057 pRoamProfile->ChannelInfo.ChannelList =
9058 &pHddStaCtx->conn_info.operationChannel;
9059 }
9060 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009061 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009062 )
9063 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309064 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9065 {
9066 if(VOS_STATUS_SUCCESS !=
9067 wlan_hdd_validate_operation_channel(pAdapter,channel))
9068 {
9069 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009070 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309071 return -EINVAL;
9072 }
9073 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9074 }
9075 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009076 {
9077 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9078
9079 /* If auto channel selection is configured as enable/ 1 then ignore
9080 channel set by supplicant
9081 */
9082 if ( cfg_param->apAutoChannelSelection )
9083 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309084 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9085 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009086 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309087 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9088 __func__, hdd_device_modetoString(pAdapter->device_mode),
9089 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009090 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309091 else
9092 {
9093 if(VOS_STATUS_SUCCESS !=
9094 wlan_hdd_validate_operation_channel(pAdapter,channel))
9095 {
9096 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009097 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309098 return -EINVAL;
9099 }
9100 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9101 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009102 }
9103 }
9104 else
9105 {
9106 hddLog(VOS_TRACE_LEVEL_FATAL,
9107 "%s: Invalid device mode failed to set valid channel", __func__);
9108 return -EINVAL;
9109 }
9110 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309111 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009112}
9113
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309114static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9115 struct net_device *dev,
9116 struct ieee80211_channel *chan,
9117 enum nl80211_channel_type channel_type
9118 )
9119{
9120 int ret;
9121
9122 vos_ssr_protect(__func__);
9123 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9124 vos_ssr_unprotect(__func__);
9125
9126 return ret;
9127}
9128
Jeff Johnson295189b2012-06-20 16:38:30 -07009129#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9130static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9131 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009132#else
9133static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9134 struct cfg80211_beacon_data *params,
9135 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309136 enum nl80211_hidden_ssid hidden_ssid,
9137 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009138#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009139{
9140 tsap_Config_t *pConfig;
9141 beacon_data_t *pBeacon = NULL;
9142 struct ieee80211_mgmt *pMgmt_frame;
9143 v_U8_t *pIe=NULL;
9144 v_U16_t capab_info;
9145 eCsrAuthType RSNAuthType;
9146 eCsrEncryptionType RSNEncryptType;
9147 eCsrEncryptionType mcRSNEncryptType;
9148 int status = VOS_STATUS_SUCCESS;
9149 tpWLAN_SAPEventCB pSapEventCallback;
9150 hdd_hostapd_state_t *pHostapdState;
9151 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
9152 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309153 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009154 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309155 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009156 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009157 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309158 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009159 v_BOOL_t MFPCapable = VOS_FALSE;
9160 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309161 v_BOOL_t sapEnable11AC =
9162 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07009163 ENTER();
9164
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309165 iniConfig = pHddCtx->cfg_ini;
9166
Jeff Johnson295189b2012-06-20 16:38:30 -07009167 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9168
9169 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9170
9171 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9172
9173 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9174
9175 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9176
9177 //channel is already set in the set_channel Call back
9178 //pConfig->channel = pCommitConfig->channel;
9179
9180 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309181 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009182 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9183
9184 pConfig->dtim_period = pBeacon->dtim_period;
9185
Arif Hussain6d2a3322013-11-17 19:50:10 -08009186 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009187 pConfig->dtim_period);
9188
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009189 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009190 {
9191 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009192 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309193 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9194 {
9195 tANI_BOOLEAN restartNeeded;
9196 pConfig->ieee80211d = 1;
9197 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9198 sme_setRegInfo(hHal, pConfig->countryCode);
9199 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9200 }
9201 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009202 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009203 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009204 pConfig->ieee80211d = 1;
9205 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9206 sme_setRegInfo(hHal, pConfig->countryCode);
9207 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009208 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009209 else
9210 {
9211 pConfig->ieee80211d = 0;
9212 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309213 /*
9214 * If auto channel is configured i.e. channel is 0,
9215 * so skip channel validation.
9216 */
9217 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9218 {
9219 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9220 {
9221 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009222 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309223 return -EINVAL;
9224 }
9225 }
9226 else
9227 {
9228 if(1 != pHddCtx->is_dynamic_channel_range_set)
9229 {
9230 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9231 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9232 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9233 }
9234 pHddCtx->is_dynamic_channel_range_set = 0;
9235 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009236 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009237 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009238 {
9239 pConfig->ieee80211d = 0;
9240 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309241
9242#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9243 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9244 pConfig->authType = eSAP_OPEN_SYSTEM;
9245 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9246 pConfig->authType = eSAP_SHARED_KEY;
9247 else
9248 pConfig->authType = eSAP_AUTO_SWITCH;
9249#else
9250 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9251 pConfig->authType = eSAP_OPEN_SYSTEM;
9252 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9253 pConfig->authType = eSAP_SHARED_KEY;
9254 else
9255 pConfig->authType = eSAP_AUTO_SWITCH;
9256#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009257
9258 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309259
9260 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009261 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
9262
9263 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9264
9265 /*Set wps station to configured*/
9266 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9267
9268 if(pIe)
9269 {
9270 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9271 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009272 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009273 return -EINVAL;
9274 }
9275 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9276 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009277 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009278 /* Check 15 bit of WPS IE as it contain information for wps state
9279 * WPS state
9280 */
9281 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9282 {
9283 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9284 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9285 {
9286 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9287 }
9288 }
9289 }
9290 else
9291 {
9292 pConfig->wps_state = SAP_WPS_DISABLED;
9293 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309294 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009295
c_hpothufe599e92014-06-16 11:38:55 +05309296 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9297 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9298 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9299 eCSR_ENCRYPT_TYPE_NONE;
9300
Jeff Johnson295189b2012-06-20 16:38:30 -07009301 pConfig->RSNWPAReqIELength = 0;
9302 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309303 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009304 WLAN_EID_RSN);
9305 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309306 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009307 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9308 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9309 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309310 /* The actual processing may eventually be more extensive than
9311 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009312 * by the app.
9313 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309314 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009315 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9316 &RSNEncryptType,
9317 &mcRSNEncryptType,
9318 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009319 &MFPCapable,
9320 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009321 pConfig->pRSNWPAReqIE[1]+2,
9322 pConfig->pRSNWPAReqIE );
9323
9324 if( VOS_STATUS_SUCCESS == status )
9325 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309326 /* Now copy over all the security attributes you have
9327 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009328 * */
9329 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9330 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9331 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9332 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309333 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009334 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009335 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9336 }
9337 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309338
Jeff Johnson295189b2012-06-20 16:38:30 -07009339 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9340 pBeacon->tail, pBeacon->tail_len);
9341
9342 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9343 {
9344 if (pConfig->pRSNWPAReqIE)
9345 {
9346 /*Mixed mode WPA/WPA2*/
9347 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
9348 pConfig->RSNWPAReqIELength += pIe[1] + 2;
9349 }
9350 else
9351 {
9352 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9353 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9354 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309355 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009356 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9357 &RSNEncryptType,
9358 &mcRSNEncryptType,
9359 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009360 &MFPCapable,
9361 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009362 pConfig->pRSNWPAReqIE[1]+2,
9363 pConfig->pRSNWPAReqIE );
9364
9365 if( VOS_STATUS_SUCCESS == status )
9366 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309367 /* Now copy over all the security attributes you have
9368 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009369 * */
9370 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9371 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9372 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9373 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309374 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009375 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009376 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9377 }
9378 }
9379 }
9380
Jeff Johnson4416a782013-03-25 14:17:50 -07009381 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
9382 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9383 return -EINVAL;
9384 }
9385
Jeff Johnson295189b2012-06-20 16:38:30 -07009386 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9387
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009388#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009389 if (params->ssid != NULL)
9390 {
9391 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9392 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9393 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9394 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9395 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009396#else
9397 if (ssid != NULL)
9398 {
9399 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9400 pConfig->SSIDinfo.ssid.length = ssid_len;
9401 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9402 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9403 }
9404#endif
9405
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309406 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009407 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309408
Jeff Johnson295189b2012-06-20 16:38:30 -07009409 /* default value */
9410 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9411 pConfig->num_accept_mac = 0;
9412 pConfig->num_deny_mac = 0;
9413
9414 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9415 pBeacon->tail, pBeacon->tail_len);
9416
9417 /* pIe for black list is following form:
9418 type : 1 byte
9419 length : 1 byte
9420 OUI : 4 bytes
9421 acl type : 1 byte
9422 no of mac addr in black list: 1 byte
9423 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309424 */
9425 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009426 {
9427 pConfig->SapMacaddr_acl = pIe[6];
9428 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009429 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009430 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309431 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9432 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009433 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9434 for (i = 0; i < pConfig->num_deny_mac; i++)
9435 {
9436 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9437 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309438 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009439 }
9440 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9441 pBeacon->tail, pBeacon->tail_len);
9442
9443 /* pIe for white list is following form:
9444 type : 1 byte
9445 length : 1 byte
9446 OUI : 4 bytes
9447 acl type : 1 byte
9448 no of mac addr in white list: 1 byte
9449 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309450 */
9451 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009452 {
9453 pConfig->SapMacaddr_acl = pIe[6];
9454 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009455 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009456 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309457 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9458 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009459 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9460 for (i = 0; i < pConfig->num_accept_mac; i++)
9461 {
9462 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9463 acl_entry++;
9464 }
9465 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309466
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9468
Jeff Johnsone7245742012-09-05 17:12:55 -07009469#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009470 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309471 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9472 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309473 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9474 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009475 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9476 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309477 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9478 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009479 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309480 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009481 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309482 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009483
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309484 /* If ACS disable and selected channel <= 14
9485 * OR
9486 * ACS enabled and ACS operating band is choosen as 2.4
9487 * AND
9488 * VHT in 2.4G Disabled
9489 * THEN
9490 * Fallback to 11N mode
9491 */
9492 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9493 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309494 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309495 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009496 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309497 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9498 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009499 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9500 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009501 }
9502#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309503
Jeff Johnson295189b2012-06-20 16:38:30 -07009504 // ht_capab is not what the name conveys,this is used for protection bitmap
9505 pConfig->ht_capab =
9506 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9507
9508 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
9509 {
9510 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9511 return -EINVAL;
9512 }
9513
9514 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309515 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009516 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9517 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309518 pConfig->obssProtEnabled =
9519 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009520
Chet Lanctot8cecea22014-02-11 19:09:36 -08009521#ifdef WLAN_FEATURE_11W
9522 pConfig->mfpCapable = MFPCapable;
9523 pConfig->mfpRequired = MFPRequired;
9524 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9525 pConfig->mfpCapable, pConfig->mfpRequired);
9526#endif
9527
Arif Hussain6d2a3322013-11-17 19:50:10 -08009528 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009529 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009530 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9531 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9532 (int)pConfig->channel);
9533 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9534 pConfig->SapHw_mode, pConfig->privacy,
9535 pConfig->authType);
9536 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9537 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9538 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9539 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009540
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309541 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009542 {
9543 //Bss already started. just return.
9544 //TODO Probably it should update some beacon params.
9545 hddLog( LOGE, "Bss Already started...Ignore the request");
9546 EXIT();
9547 return 0;
9548 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309549
Agarwal Ashish51325b52014-06-16 16:50:49 +05309550 if (vos_max_concurrent_connections_reached()) {
9551 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9552 return -EINVAL;
9553 }
9554
Jeff Johnson295189b2012-06-20 16:38:30 -07009555 pConfig->persona = pHostapdAdapter->device_mode;
9556
Peng Xu2446a892014-09-05 17:21:18 +05309557 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9558 if ( NULL != psmeConfig)
9559 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309560 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309561 sme_GetConfigParam(hHal, psmeConfig);
9562 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309563#ifdef WLAN_FEATURE_AP_HT40_24G
9564 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9565 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9566 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9567 {
9568 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9569 sme_UpdateConfig (hHal, psmeConfig);
9570 }
9571#endif
Peng Xu2446a892014-09-05 17:21:18 +05309572 vos_mem_free(psmeConfig);
9573 }
Peng Xuafc34e32014-09-25 13:23:55 +05309574 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309575
Jeff Johnson295189b2012-06-20 16:38:30 -07009576 pSapEventCallback = hdd_hostapd_SAPEventCB;
9577 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9578 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9579 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009580 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009581 return -EINVAL;
9582 }
9583
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309584 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009585 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9586
9587 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309588
Jeff Johnson295189b2012-06-20 16:38:30 -07009589 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309590 {
9591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009592 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009593 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009594 VOS_ASSERT(0);
9595 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309596
Jeff Johnson295189b2012-06-20 16:38:30 -07009597 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309598 /* Initialize WMM configuation */
9599 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309600 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009601
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009602#ifdef WLAN_FEATURE_P2P_DEBUG
9603 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9604 {
9605 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9606 {
9607 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9608 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009609 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009610 }
9611 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9612 {
9613 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9614 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009615 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009616 }
9617 }
9618#endif
9619
Jeff Johnson295189b2012-06-20 16:38:30 -07009620 pHostapdState->bCommit = TRUE;
9621 EXIT();
9622
9623 return 0;
9624}
9625
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009626#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309627static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309628 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009629 struct beacon_parameters *params)
9630{
9631 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309632 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309633 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009634
9635 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309636
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309637 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9638 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9639 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309640 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9641 hdd_device_modetoString(pAdapter->device_mode),
9642 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009643
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309644 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9645 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309646 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009647 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309648 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009649 }
9650
Agarwal Ashish51325b52014-06-16 16:50:49 +05309651 if (vos_max_concurrent_connections_reached()) {
9652 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9653 return -EINVAL;
9654 }
9655
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309656 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009657 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009658 )
9659 {
9660 beacon_data_t *old,*new;
9661
9662 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309663
Jeff Johnson295189b2012-06-20 16:38:30 -07009664 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309665 {
9666 hddLog(VOS_TRACE_LEVEL_WARN,
9667 FL("already beacon info added to session(%d)"),
9668 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009669 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309670 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009671
9672 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9673
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309674 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 {
9676 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009677 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009678 return -EINVAL;
9679 }
9680
9681 pAdapter->sessionCtx.ap.beacon = new;
9682
9683 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9684 }
9685
9686 EXIT();
9687 return status;
9688}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309689
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309690static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9691 struct net_device *dev,
9692 struct beacon_parameters *params)
9693{
9694 int ret;
9695
9696 vos_ssr_protect(__func__);
9697 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
9698 vos_ssr_unprotect(__func__);
9699
9700 return ret;
9701}
9702
9703static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009704 struct net_device *dev,
9705 struct beacon_parameters *params)
9706{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309707 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309708 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9709 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309710 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009711
9712 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309713
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309714 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9715 TRACE_CODE_HDD_CFG80211_SET_BEACON,
9716 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
9717 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9718 __func__, hdd_device_modetoString(pAdapter->device_mode),
9719 pAdapter->device_mode);
9720
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309721 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9722 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309723 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009724 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309725 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009726 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309727
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309728 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009729 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309730 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009731 {
9732 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309733
Jeff Johnson295189b2012-06-20 16:38:30 -07009734 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309735
Jeff Johnson295189b2012-06-20 16:38:30 -07009736 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309737 {
9738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9739 FL("session(%d) old and new heads points to NULL"),
9740 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009741 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309742 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009743
9744 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9745
9746 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309747 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009748 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009749 return -EINVAL;
9750 }
9751
9752 pAdapter->sessionCtx.ap.beacon = new;
9753
9754 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9755 }
9756
9757 EXIT();
9758 return status;
9759}
9760
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309761static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
9762 struct net_device *dev,
9763 struct beacon_parameters *params)
9764{
9765 int ret;
9766
9767 vos_ssr_protect(__func__);
9768 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
9769 vos_ssr_unprotect(__func__);
9770
9771 return ret;
9772}
9773
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009774#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9775
9776#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309777static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009778 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009779#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309780static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009781 struct net_device *dev)
9782#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009783{
9784 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07009785 hdd_context_t *pHddCtx = NULL;
9786 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309787 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309788 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009789
9790 ENTER();
9791
9792 if (NULL == pAdapter)
9793 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009795 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009796 return -ENODEV;
9797 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009798
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309799 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9800 TRACE_CODE_HDD_CFG80211_STOP_AP,
9801 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309802 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9803 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309804 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009805 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309806 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07009807 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009808
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009809 pScanInfo = &pHddCtx->scan_info;
9810
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309811 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9812 __func__, hdd_device_modetoString(pAdapter->device_mode),
9813 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009814
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309815 ret = wlan_hdd_scan_abort(pAdapter);
9816
Girish Gowli4bf7a632014-06-12 13:42:11 +05309817 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07009818 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9820 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309821
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309822 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07009823 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9825 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08009826
Jeff Johnsone7245742012-09-05 17:12:55 -07009827 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309828 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07009829 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309830 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009831 }
9832
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05309833 /* Delete all associated STAs before stopping AP/P2P GO */
9834 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05309835 hdd_hostapd_stop(dev);
9836
Jeff Johnson295189b2012-06-20 16:38:30 -07009837 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009838 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009839 )
9840 {
9841 beacon_data_t *old;
9842
9843 old = pAdapter->sessionCtx.ap.beacon;
9844
9845 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309846 {
9847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9848 FL("session(%d) beacon data points to NULL"),
9849 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009850 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309851 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009852
Jeff Johnson295189b2012-06-20 16:38:30 -07009853 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009854
9855 mutex_lock(&pHddCtx->sap_lock);
9856 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9857 {
Jeff Johnson4416a782013-03-25 14:17:50 -07009858 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009859 {
9860 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9861
9862 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9863
9864 if (!VOS_IS_STATUS_SUCCESS(status))
9865 {
9866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009867 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009868 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309869 }
9870 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309872 /* BSS stopped, clear the active sessions for this device mode */
9873 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009874 }
9875 mutex_unlock(&pHddCtx->sap_lock);
9876
9877 if(status != VOS_STATUS_SUCCESS)
9878 {
9879 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009880 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009881 return -EINVAL;
9882 }
9883
Jeff Johnson4416a782013-03-25 14:17:50 -07009884 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009885 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
9886 ==eHAL_STATUS_FAILURE)
9887 {
9888 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009889 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009890 }
9891
Jeff Johnson4416a782013-03-25 14:17:50 -07009892 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009893 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9894 eANI_BOOLEAN_FALSE) )
9895 {
9896 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009897 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009898 }
9899
9900 // Reset WNI_CFG_PROBE_RSP Flags
9901 wlan_hdd_reset_prob_rspies(pAdapter);
9902
9903 pAdapter->sessionCtx.ap.beacon = NULL;
9904 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009905#ifdef WLAN_FEATURE_P2P_DEBUG
9906 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
9907 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
9908 {
9909 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
9910 "GO got removed");
9911 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
9912 }
9913#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009914 }
9915 EXIT();
9916 return status;
9917}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009918
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309919#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9920static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
9921 struct net_device *dev)
9922{
9923 int ret;
9924
9925 vos_ssr_protect(__func__);
9926 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
9927 vos_ssr_unprotect(__func__);
9928
9929 return ret;
9930}
9931#else
9932static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
9933 struct net_device *dev)
9934{
9935 int ret;
9936
9937 vos_ssr_protect(__func__);
9938 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
9939 vos_ssr_unprotect(__func__);
9940
9941 return ret;
9942}
9943#endif
9944
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009945#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
9946
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309947static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309948 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009949 struct cfg80211_ap_settings *params)
9950{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309951 hdd_adapter_t *pAdapter;
9952 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309953 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009954
9955 ENTER();
9956
Girish Gowlib143d7a2015-02-18 19:39:55 +05309957 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009958 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309959 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05309960 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309961 return -ENODEV;
9962 }
9963
9964 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9965 if (NULL == pAdapter)
9966 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309967 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309968 "%s: HDD adapter is Null", __func__);
9969 return -ENODEV;
9970 }
9971
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309972 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9973 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
9974 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309975 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9976 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309977 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309978 "%s: HDD adapter magic is invalid", __func__);
9979 return -ENODEV;
9980 }
9981
9982 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309983 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309984 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309985 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309986 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309987 }
9988
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309989 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
9990 __func__, hdd_device_modetoString(pAdapter->device_mode),
9991 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309992
9993 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009994 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009995 )
9996 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309997 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009998
9999 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010000
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010001 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010002 {
10003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10004 FL("already beacon info added to session(%d)"),
10005 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010006 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010007 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010008
Girish Gowlib143d7a2015-02-18 19:39:55 +053010009#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10010 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10011 &new,
10012 &params->beacon);
10013#else
10014 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10015 &new,
10016 &params->beacon,
10017 params->dtim_period);
10018#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010019
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010020 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010021 {
10022 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010023 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010024 return -EINVAL;
10025 }
10026 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010027#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010028 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10029#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10030 params->channel, params->channel_type);
10031#else
10032 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10033#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010034#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010035 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010036 params->ssid_len, params->hidden_ssid,
10037 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010038 }
10039
10040 EXIT();
10041 return status;
10042}
10043
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010044static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10045 struct net_device *dev,
10046 struct cfg80211_ap_settings *params)
10047{
10048 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010049
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010050 vos_ssr_protect(__func__);
10051 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10052 vos_ssr_unprotect(__func__);
10053
10054 return ret;
10055}
10056
10057static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010058 struct net_device *dev,
10059 struct cfg80211_beacon_data *params)
10060{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010061 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010062 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010063 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010064
10065 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010066
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010067 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10068 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10069 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010070 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010071 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010072
10073 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10074 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010075 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010076 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010077 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010078 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010079
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010080 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010081 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010082 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010083 {
10084 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010085
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010086 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010087
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010088 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010089 {
10090 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10091 FL("session(%d) beacon data points to NULL"),
10092 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010093 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010094 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010095
10096 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10097
10098 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010099 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010100 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010101 return -EINVAL;
10102 }
10103
10104 pAdapter->sessionCtx.ap.beacon = new;
10105
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010106 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10107 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010108 }
10109
10110 EXIT();
10111 return status;
10112}
10113
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010114static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10115 struct net_device *dev,
10116 struct cfg80211_beacon_data *params)
10117{
10118 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010119
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010120 vos_ssr_protect(__func__);
10121 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10122 vos_ssr_unprotect(__func__);
10123
10124 return ret;
10125}
10126
10127#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010128
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010129static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010130 struct net_device *dev,
10131 struct bss_parameters *params)
10132{
10133 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010134 hdd_context_t *pHddCtx;
10135 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010136
10137 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010138
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010139 if (NULL == pAdapter)
10140 {
10141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10142 "%s: HDD adapter is Null", __func__);
10143 return -ENODEV;
10144 }
10145 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010146 ret = wlan_hdd_validate_context(pHddCtx);
10147 if (0 != ret)
10148 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010149 return ret;
10150 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010151 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10152 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10153 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010154 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10155 __func__, hdd_device_modetoString(pAdapter->device_mode),
10156 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010157
10158 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010159 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010160 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010161 {
10162 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10163 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010164 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010165 {
10166 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010167 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010168 }
10169
10170 EXIT();
10171 return 0;
10172}
10173
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010174static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10175 struct net_device *dev,
10176 struct bss_parameters *params)
10177{
10178 int ret;
10179
10180 vos_ssr_protect(__func__);
10181 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10182 vos_ssr_unprotect(__func__);
10183
10184 return ret;
10185}
Kiet Lam10841362013-11-01 11:36:50 +053010186/* FUNCTION: wlan_hdd_change_country_code_cd
10187* to wait for contry code completion
10188*/
10189void* wlan_hdd_change_country_code_cb(void *pAdapter)
10190{
10191 hdd_adapter_t *call_back_pAdapter = pAdapter;
10192 complete(&call_back_pAdapter->change_country_code);
10193 return NULL;
10194}
10195
Jeff Johnson295189b2012-06-20 16:38:30 -070010196/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010197 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010198 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10199 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010200int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010201 struct net_device *ndev,
10202 enum nl80211_iftype type,
10203 u32 *flags,
10204 struct vif_params *params
10205 )
10206{
10207 struct wireless_dev *wdev;
10208 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010209 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010210 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010211 tCsrRoamProfile *pRoamProfile = NULL;
10212 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010213 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010214 eMib_dot11DesiredBssType connectedBssType;
10215 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010216 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010217
10218 ENTER();
10219
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010220 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010221 {
10222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10223 "%s: Adapter context is null", __func__);
10224 return VOS_STATUS_E_FAILURE;
10225 }
10226
10227 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10228 if (!pHddCtx)
10229 {
10230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10231 "%s: HDD context is null", __func__);
10232 return VOS_STATUS_E_FAILURE;
10233 }
10234
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010235 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10236 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10237 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010238 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010239 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010240 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010241 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010242 }
10243
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010244 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10245 __func__, hdd_device_modetoString(pAdapter->device_mode),
10246 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010247
Agarwal Ashish51325b52014-06-16 16:50:49 +053010248 if (vos_max_concurrent_connections_reached()) {
10249 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10250 return -EINVAL;
10251 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010252 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010253 wdev = ndev->ieee80211_ptr;
10254
10255#ifdef WLAN_BTAMP_FEATURE
10256 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10257 (NL80211_IFTYPE_ADHOC == type)||
10258 (NL80211_IFTYPE_AP == type)||
10259 (NL80211_IFTYPE_P2P_GO == type))
10260 {
10261 pHddCtx->isAmpAllowed = VOS_FALSE;
10262 // stop AMP traffic
10263 status = WLANBAP_StopAmp();
10264 if(VOS_STATUS_SUCCESS != status )
10265 {
10266 pHddCtx->isAmpAllowed = VOS_TRUE;
10267 hddLog(VOS_TRACE_LEVEL_FATAL,
10268 "%s: Failed to stop AMP", __func__);
10269 return -EINVAL;
10270 }
10271 }
10272#endif //WLAN_BTAMP_FEATURE
10273 /* Reset the current device mode bit mask*/
10274 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10275
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010276 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10277 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10278 (type == NL80211_IFTYPE_P2P_GO)))
10279 {
10280 /* Notify Mode change in case of concurrency.
10281 * Below function invokes TDLS teardown Functionality Since TDLS is
10282 * not Supported in case of concurrency i.e Once P2P session
10283 * is detected disable offchannel and teardown TDLS links
10284 */
10285 hddLog(LOG1,
10286 FL("Device mode = %d Interface type = %d"),
10287 pAdapter->device_mode, type);
10288 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10289 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010290
Jeff Johnson295189b2012-06-20 16:38:30 -070010291 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010292 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010293 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010294 )
10295 {
10296 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010297 if (!pWextState)
10298 {
10299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10300 "%s: pWextState is null", __func__);
10301 return VOS_STATUS_E_FAILURE;
10302 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010303 pRoamProfile = &pWextState->roamProfile;
10304 LastBSSType = pRoamProfile->BSSType;
10305
10306 switch (type)
10307 {
10308 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010309 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010310 hddLog(VOS_TRACE_LEVEL_INFO,
10311 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10312 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010313#ifdef WLAN_FEATURE_11AC
10314 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10315 {
10316 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10317 }
10318#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010319 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010320 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010321 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010322 //Check for sub-string p2p to confirm its a p2p interface
10323 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010324 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010325#ifdef FEATURE_WLAN_TDLS
10326 mutex_lock(&pHddCtx->tdls_lock);
10327 wlan_hdd_tdls_exit(pAdapter, TRUE);
10328 mutex_unlock(&pHddCtx->tdls_lock);
10329#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010330 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10331 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10332 }
10333 else
10334 {
10335 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010336 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010337 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010338 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010339
Jeff Johnson295189b2012-06-20 16:38:30 -070010340 case NL80211_IFTYPE_ADHOC:
10341 hddLog(VOS_TRACE_LEVEL_INFO,
10342 "%s: setting interface Type to ADHOC", __func__);
10343 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10344 pRoamProfile->phyMode =
10345 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010346 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010347 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010348 hdd_set_ibss_ops( pAdapter );
10349 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010350
10351 status = hdd_sta_id_hash_attach(pAdapter);
10352 if (VOS_STATUS_SUCCESS != status) {
10353 hddLog(VOS_TRACE_LEVEL_ERROR,
10354 FL("Failed to initialize hash for IBSS"));
10355 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010356 break;
10357
10358 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010359 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010360 {
10361 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10362 "%s: setting interface Type to %s", __func__,
10363 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10364
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010365 //Cancel any remain on channel for GO mode
10366 if (NL80211_IFTYPE_P2P_GO == type)
10367 {
10368 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10369 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010370 if (NL80211_IFTYPE_AP == type)
10371 {
10372 /* As Loading WLAN Driver one interface being created for p2p device
10373 * address. This will take one HW STA and the max number of clients
10374 * that can connect to softAP will be reduced by one. so while changing
10375 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10376 * interface as it is not required in SoftAP mode.
10377 */
10378
10379 // Get P2P Adapter
10380 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10381
10382 if (pP2pAdapter)
10383 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010384 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010385 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010386 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10387 }
10388 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010389 //Disable IMPS & BMPS for SAP/GO
10390 if(VOS_STATUS_E_FAILURE ==
10391 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10392 {
10393 //Fail to Exit BMPS
10394 VOS_ASSERT(0);
10395 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010396
10397 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10398
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010399#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010400
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010401 /* A Mutex Lock is introduced while changing the mode to
10402 * protect the concurrent access for the Adapters by TDLS
10403 * module.
10404 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010405 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010406#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010407 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010408 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010409 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010410 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10411 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010412#ifdef FEATURE_WLAN_TDLS
10413 mutex_unlock(&pHddCtx->tdls_lock);
10414#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010415 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10416 (pConfig->apRandomBssidEnabled))
10417 {
10418 /* To meet Android requirements create a randomized
10419 MAC address of the form 02:1A:11:Fx:xx:xx */
10420 get_random_bytes(&ndev->dev_addr[3], 3);
10421 ndev->dev_addr[0] = 0x02;
10422 ndev->dev_addr[1] = 0x1A;
10423 ndev->dev_addr[2] = 0x11;
10424 ndev->dev_addr[3] |= 0xF0;
10425 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10426 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010427 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10428 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010429 }
10430
Jeff Johnson295189b2012-06-20 16:38:30 -070010431 hdd_set_ap_ops( pAdapter->dev );
10432
Kiet Lam10841362013-11-01 11:36:50 +053010433 /* This is for only SAP mode where users can
10434 * control country through ini.
10435 * P2P GO follows station country code
10436 * acquired during the STA scanning. */
10437 if((NL80211_IFTYPE_AP == type) &&
10438 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10439 {
10440 int status = 0;
10441 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10442 "%s: setting country code from INI ", __func__);
10443 init_completion(&pAdapter->change_country_code);
10444 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10445 (void *)(tSmeChangeCountryCallback)
10446 wlan_hdd_change_country_code_cb,
10447 pConfig->apCntryCode, pAdapter,
10448 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010449 eSIR_FALSE,
10450 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010451 if (eHAL_STATUS_SUCCESS == status)
10452 {
10453 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010454 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010455 &pAdapter->change_country_code,
10456 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010457 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010458 {
10459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010460 FL("SME Timed out while setting country code %ld"),
10461 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010462
10463 if (pHddCtx->isLogpInProgress)
10464 {
10465 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10466 "%s: LOGP in Progress. Ignore!!!", __func__);
10467 return -EAGAIN;
10468 }
Kiet Lam10841362013-11-01 11:36:50 +053010469 }
10470 }
10471 else
10472 {
10473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010474 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010475 return -EINVAL;
10476 }
10477 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010478 status = hdd_init_ap_mode(pAdapter);
10479 if(status != VOS_STATUS_SUCCESS)
10480 {
10481 hddLog(VOS_TRACE_LEVEL_FATAL,
10482 "%s: Error initializing the ap mode", __func__);
10483 return -EINVAL;
10484 }
10485 hdd_set_conparam(1);
10486
Nirav Shah7e3c8132015-06-22 23:51:42 +053010487 status = hdd_sta_id_hash_attach(pAdapter);
10488 if (VOS_STATUS_SUCCESS != status)
10489 {
10490 hddLog(VOS_TRACE_LEVEL_ERROR,
10491 FL("Failed to initialize hash for AP"));
10492 return -EINVAL;
10493 }
10494
Jeff Johnson295189b2012-06-20 16:38:30 -070010495 /*interface type changed update in wiphy structure*/
10496 if(wdev)
10497 {
10498 wdev->iftype = type;
10499 pHddCtx->change_iface = type;
10500 }
10501 else
10502 {
10503 hddLog(VOS_TRACE_LEVEL_ERROR,
10504 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10505 return -EINVAL;
10506 }
10507 goto done;
10508 }
10509
10510 default:
10511 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10512 __func__);
10513 return -EOPNOTSUPP;
10514 }
10515 }
10516 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010517 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010518 )
10519 {
10520 switch(type)
10521 {
10522 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010523 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010524 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010525
10526 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010527#ifdef FEATURE_WLAN_TDLS
10528
10529 /* A Mutex Lock is introduced while changing the mode to
10530 * protect the concurrent access for the Adapters by TDLS
10531 * module.
10532 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010533 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010534#endif
c_hpothu002231a2015-02-05 14:58:51 +053010535 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010536 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010537 //Check for sub-string p2p to confirm its a p2p interface
10538 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010539 {
10540 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10541 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10542 }
10543 else
10544 {
10545 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010546 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010547 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010548 hdd_set_conparam(0);
10549 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010550 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10551 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010552#ifdef FEATURE_WLAN_TDLS
10553 mutex_unlock(&pHddCtx->tdls_lock);
10554#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010555 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010556 if( VOS_STATUS_SUCCESS != status )
10557 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010558 /* In case of JB, for P2P-GO, only change interface will be called,
10559 * This is the right place to enable back bmps_imps()
10560 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010561 if (pHddCtx->hdd_wlan_suspended)
10562 {
10563 hdd_set_pwrparams(pHddCtx);
10564 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010565 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010566 goto done;
10567 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010568 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010569 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010570 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10571 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010572 goto done;
10573 default:
10574 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10575 __func__);
10576 return -EOPNOTSUPP;
10577
10578 }
10579
10580 }
10581 else
10582 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010583 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10584 __func__, hdd_device_modetoString(pAdapter->device_mode),
10585 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010586 return -EOPNOTSUPP;
10587 }
10588
10589
10590 if(pRoamProfile)
10591 {
10592 if ( LastBSSType != pRoamProfile->BSSType )
10593 {
10594 /*interface type changed update in wiphy structure*/
10595 wdev->iftype = type;
10596
10597 /*the BSS mode changed, We need to issue disconnect
10598 if connected or in IBSS disconnect state*/
10599 if ( hdd_connGetConnectedBssType(
10600 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10601 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10602 {
10603 /*need to issue a disconnect to CSR.*/
10604 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10605 if( eHAL_STATUS_SUCCESS ==
10606 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10607 pAdapter->sessionId,
10608 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10609 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010610 ret = wait_for_completion_interruptible_timeout(
10611 &pAdapter->disconnect_comp_var,
10612 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10613 if (ret <= 0)
10614 {
10615 hddLog(VOS_TRACE_LEVEL_ERROR,
10616 FL("wait on disconnect_comp_var failed %ld"), ret);
10617 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010618 }
10619 }
10620 }
10621 }
10622
10623done:
10624 /*set bitmask based on updated value*/
10625 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010626
10627 /* Only STA mode support TM now
10628 * all other mode, TM feature should be disabled */
10629 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10630 (~VOS_STA & pHddCtx->concurrency_mode) )
10631 {
10632 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10633 }
10634
Jeff Johnson295189b2012-06-20 16:38:30 -070010635#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010636 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010637 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010638 {
10639 //we are ok to do AMP
10640 pHddCtx->isAmpAllowed = VOS_TRUE;
10641 }
10642#endif //WLAN_BTAMP_FEATURE
10643 EXIT();
10644 return 0;
10645}
10646
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010647/*
10648 * FUNCTION: wlan_hdd_cfg80211_change_iface
10649 * wrapper function to protect the actual implementation from SSR.
10650 */
10651int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10652 struct net_device *ndev,
10653 enum nl80211_iftype type,
10654 u32 *flags,
10655 struct vif_params *params
10656 )
10657{
10658 int ret;
10659
10660 vos_ssr_protect(__func__);
10661 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10662 vos_ssr_unprotect(__func__);
10663
10664 return ret;
10665}
10666
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010667#ifdef FEATURE_WLAN_TDLS
10668static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010669 struct net_device *dev,
10670#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10671 const u8 *mac,
10672#else
10673 u8 *mac,
10674#endif
10675 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010676{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010677 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010678 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010679 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010680 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010681 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010682 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010683
10684 ENTER();
10685
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010686 if (!dev) {
10687 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10688 return -EINVAL;
10689 }
10690
10691 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10692 if (!pAdapter) {
10693 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
10694 return -EINVAL;
10695 }
10696
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010697 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010698 {
10699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10700 "Invalid arguments");
10701 return -EINVAL;
10702 }
Hoonki Lee27511902013-03-14 18:19:06 -070010703
10704 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
10705 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
10706 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070010708 "%s: TDLS mode is disabled OR not enabled in FW."
10709 MAC_ADDRESS_STR " Request declined.",
10710 __func__, MAC_ADDR_ARRAY(mac));
10711 return -ENOTSUPP;
10712 }
10713
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010714 if (pHddCtx->isLogpInProgress)
10715 {
10716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10717 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053010718 wlan_hdd_tdls_set_link_status(pAdapter,
10719 mac,
10720 eTDLS_LINK_IDLE,
10721 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010722 return -EBUSY;
10723 }
10724
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010725 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053010726 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010727
10728 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010730 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
10731 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010732 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010733 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010734 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010735
10736 /* in add station, we accept existing valid staId if there is */
10737 if ((0 == update) &&
10738 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
10739 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010740 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010742 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010743 " link_status %d. staId %d. add station ignored.",
10744 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010745 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010746 return 0;
10747 }
10748 /* in change station, we accept only when staId is valid */
10749 if ((1 == update) &&
10750 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
10751 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
10752 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010753 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010755 "%s: " MAC_ADDRESS_STR
10756 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010757 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
10758 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
10759 mutex_unlock(&pHddCtx->tdls_lock);
10760 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010761 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010762 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010763
10764 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053010765 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010766 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010767 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10768 "%s: " MAC_ADDRESS_STR
10769 " TDLS setup is ongoing. Request declined.",
10770 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070010771 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010772 }
10773
10774 /* first to check if we reached to maximum supported TDLS peer.
10775 TODO: for now, return -EPERM looks working fine,
10776 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010777 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
10778 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010779 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10781 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010782 " TDLS Max peer already connected. Request declined."
10783 " Num of peers (%d), Max allowed (%d).",
10784 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
10785 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010786 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010787 }
10788 else
10789 {
10790 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010791 mutex_lock(&pHddCtx->tdls_lock);
10792 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010793 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010794 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010795 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10797 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
10798 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010799 return -EPERM;
10800 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010801 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010802 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010803 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053010804 wlan_hdd_tdls_set_link_status(pAdapter,
10805 mac,
10806 eTDLS_LINK_CONNECTING,
10807 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010808
Jeff Johnsond75fe012013-04-06 10:53:06 -070010809 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010810 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010811 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010813 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010814 if(StaParams->htcap_present)
10815 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010817 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010819 "ht_capa->extended_capabilities: %0x",
10820 StaParams->HTCap.extendedHtCapInfo);
10821 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010823 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010825 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010826 if(StaParams->vhtcap_present)
10827 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010828 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010829 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
10830 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
10831 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
10832 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010833 {
10834 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010836 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010837 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010838 "[%d]: %x ", i, StaParams->supported_rates[i]);
10839 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070010840 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010841 else if ((1 == update) && (NULL == StaParams))
10842 {
10843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10844 "%s : update is true, but staParams is NULL. Error!", __func__);
10845 return -EPERM;
10846 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010847
10848 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
10849
10850 if (!update)
10851 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010852 /*Before adding sta make sure that device exited from BMPS*/
10853 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
10854 {
10855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10856 "%s: Adding tdls peer sta. Disable BMPS", __func__);
10857 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10858 if (status != VOS_STATUS_SUCCESS) {
10859 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
10860 }
10861 }
10862
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010863 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010864 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010865 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010866 hddLog(VOS_TRACE_LEVEL_ERROR,
10867 FL("Failed to add TDLS peer STA. Enable Bmps"));
10868 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010869 return -EPERM;
10870 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010871 }
10872 else
10873 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010874 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010875 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010876 if (ret != eHAL_STATUS_SUCCESS) {
10877 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
10878 return -EPERM;
10879 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010880 }
10881
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010882 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010883 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
10884
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053010885 mutex_lock(&pHddCtx->tdls_lock);
10886 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
10887
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010888 if ((pTdlsPeer != NULL) &&
10889 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010890 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010891 hddLog(VOS_TRACE_LEVEL_ERROR,
10892 FL("peer link status %u"), pTdlsPeer->link_status);
10893 mutex_unlock(&pHddCtx->tdls_lock);
10894 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010895 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053010896 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010897
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010898 if (ret <= 0)
10899 {
10900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10901 "%s: timeout waiting for tdls add station indication %ld",
10902 __func__, ret);
10903 goto error;
10904 }
10905
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010906 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
10907 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010909 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010910 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010911 }
10912
10913 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070010914
10915error:
Atul Mittal115287b2014-07-08 13:26:33 +053010916 wlan_hdd_tdls_set_link_status(pAdapter,
10917 mac,
10918 eTDLS_LINK_IDLE,
10919 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010920 return -EPERM;
10921
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010922}
10923#endif
10924
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010925static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010926 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010927#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10928 const u8 *mac,
10929#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010930 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010931#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010932 struct station_parameters *params)
10933{
10934 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010935 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010936 hdd_context_t *pHddCtx;
10937 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010938 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010939 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010940#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010941 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010942 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010943 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053010944 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010945#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010946
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010947 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010948
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010949 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010950 if ((NULL == pAdapter))
10951 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010953 "invalid adapter ");
10954 return -EINVAL;
10955 }
10956
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010957 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10958 TRACE_CODE_HDD_CHANGE_STATION,
10959 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053010960 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010961
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010962 ret = wlan_hdd_validate_context(pHddCtx);
10963 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053010964 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010965 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010966 }
10967
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010968 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10969
10970 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010971 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10973 "invalid HDD station context");
10974 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010975 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010976 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
10977
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010978 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10979 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070010980 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010981 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070010982 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010983 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070010984 WLANTL_STA_AUTHENTICATED);
10985
Gopichand Nakkala29149562013-05-10 21:43:41 +053010986 if (status != VOS_STATUS_SUCCESS)
10987 {
10988 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10989 "%s: Not able to change TL state to AUTHENTICATED", __func__);
10990 return -EINVAL;
10991 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010992 }
10993 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070010994 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
10995 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010996#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010997 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
10998 StaParams.capability = params->capability;
10999 StaParams.uapsd_queues = params->uapsd_queues;
11000 StaParams.max_sp = params->max_sp;
11001
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011002 /* Convert (first channel , number of channels) tuple to
11003 * the total list of channels. This goes with the assumption
11004 * that if the first channel is < 14, then the next channels
11005 * are an incremental of 1 else an incremental of 4 till the number
11006 * of channels.
11007 */
11008 if (0 != params->supported_channels_len) {
11009 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11010 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11011 {
11012 int wifi_chan_index;
11013 StaParams.supported_channels[j] = params->supported_channels[i];
11014 wifi_chan_index =
11015 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11016 no_of_channels = params->supported_channels[i+1];
11017 for(k=1; k <= no_of_channels; k++)
11018 {
11019 StaParams.supported_channels[j+1] =
11020 StaParams.supported_channels[j] + wifi_chan_index;
11021 j+=1;
11022 }
11023 }
11024 StaParams.supported_channels_len = j;
11025 }
11026 vos_mem_copy(StaParams.supported_oper_classes,
11027 params->supported_oper_classes,
11028 params->supported_oper_classes_len);
11029 StaParams.supported_oper_classes_len =
11030 params->supported_oper_classes_len;
11031
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011032 if (0 != params->ext_capab_len)
11033 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
11034 sizeof(StaParams.extn_capability));
11035
11036 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011037 {
11038 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011039 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011040 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011041
11042 StaParams.supported_rates_len = params->supported_rates_len;
11043
11044 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11045 * The supported_rates array , for all the structures propogating till Add Sta
11046 * to the firmware has to be modified , if the supplicant (ieee80211) is
11047 * modified to send more rates.
11048 */
11049
11050 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11051 */
11052 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11053 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11054
11055 if (0 != StaParams.supported_rates_len) {
11056 int i = 0;
11057 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11058 StaParams.supported_rates_len);
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 "Supported Rates with Length %d", StaParams.supported_rates_len);
11061 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011063 "[%d]: %0x", i, StaParams.supported_rates[i]);
11064 }
11065
11066 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011067 {
11068 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011069 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011070 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011071
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011072 if (0 != params->ext_capab_len ) {
11073 /*Define A Macro : TODO Sunil*/
11074 if ((1<<4) & StaParams.extn_capability[3]) {
11075 isBufSta = 1;
11076 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011077 /* TDLS Channel Switching Support */
11078 if ((1<<6) & StaParams.extn_capability[3]) {
11079 isOffChannelSupported = 1;
11080 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011081 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011082
11083 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
11084 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
11085
11086 /* TDLS Peer is WME/QoS capable */
11087 isQosWmmSta = TRUE;
11088 }
11089
11090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11091 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11092 __func__, isQosWmmSta, StaParams.htcap_present);
11093
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011094 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11095 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011096 isOffChannelSupported,
11097 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011098
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011099 if (VOS_STATUS_SUCCESS != status) {
11100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11101 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11102 return -EINVAL;
11103 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011104 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11105
11106 if (VOS_STATUS_SUCCESS != status) {
11107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11108 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11109 return -EINVAL;
11110 }
11111 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011112#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011113 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011114 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011115 return status;
11116}
11117
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011118#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11119static int wlan_hdd_change_station(struct wiphy *wiphy,
11120 struct net_device *dev,
11121 const u8 *mac,
11122 struct station_parameters *params)
11123#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011124static int wlan_hdd_change_station(struct wiphy *wiphy,
11125 struct net_device *dev,
11126 u8 *mac,
11127 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011128#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011129{
11130 int ret;
11131
11132 vos_ssr_protect(__func__);
11133 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11134 vos_ssr_unprotect(__func__);
11135
11136 return ret;
11137}
11138
Jeff Johnson295189b2012-06-20 16:38:30 -070011139/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011140 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011141 * This function is used to initialize the key information
11142 */
11143#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011144static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011145 struct net_device *ndev,
11146 u8 key_index, bool pairwise,
11147 const u8 *mac_addr,
11148 struct key_params *params
11149 )
11150#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011151static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011152 struct net_device *ndev,
11153 u8 key_index, const u8 *mac_addr,
11154 struct key_params *params
11155 )
11156#endif
11157{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011158 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011159 tCsrRoamSetKey setKey;
11160 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011161 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011162 v_U32_t roamId= 0xFF;
11163 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011164 hdd_hostapd_state_t *pHostapdState;
11165 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011166 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011167 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011168
11169 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011170
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011171 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11172 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11173 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011174 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11175 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011176 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011177 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011178 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011179 }
11180
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011181 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11182 __func__, hdd_device_modetoString(pAdapter->device_mode),
11183 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011184
11185 if (CSR_MAX_NUM_KEY <= key_index)
11186 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011187 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011188 key_index);
11189
11190 return -EINVAL;
11191 }
11192
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011193 if (CSR_MAX_KEY_LEN < params->key_len)
11194 {
11195 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11196 params->key_len);
11197
11198 return -EINVAL;
11199 }
11200
11201 hddLog(VOS_TRACE_LEVEL_INFO,
11202 "%s: called with key index = %d & key length %d",
11203 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011204
11205 /*extract key idx, key len and key*/
11206 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11207 setKey.keyId = key_index;
11208 setKey.keyLength = params->key_len;
11209 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11210
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011211 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011212 {
11213 case WLAN_CIPHER_SUITE_WEP40:
11214 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11215 break;
11216
11217 case WLAN_CIPHER_SUITE_WEP104:
11218 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11219 break;
11220
11221 case WLAN_CIPHER_SUITE_TKIP:
11222 {
11223 u8 *pKey = &setKey.Key[0];
11224 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11225
11226 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11227
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011228 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011229
11230 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011231 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011232 |--------------|----------|----------|
11233 <---16bytes---><--8bytes--><--8bytes-->
11234
11235 */
11236 /*Sme expects the 32 bytes key to be in the below order
11237
11238 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011239 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011240 |--------------|----------|----------|
11241 <---16bytes---><--8bytes--><--8bytes-->
11242 */
11243 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011244 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011245
11246 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011247 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011248
11249 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011250 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011251
11252
11253 break;
11254 }
11255
11256 case WLAN_CIPHER_SUITE_CCMP:
11257 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11258 break;
11259
11260#ifdef FEATURE_WLAN_WAPI
11261 case WLAN_CIPHER_SUITE_SMS4:
11262 {
11263 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11264 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11265 params->key, params->key_len);
11266 return 0;
11267 }
11268#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011269
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011270#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011271 case WLAN_CIPHER_SUITE_KRK:
11272 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11273 break;
11274#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011275
11276#ifdef WLAN_FEATURE_11W
11277 case WLAN_CIPHER_SUITE_AES_CMAC:
11278 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011279 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011280#endif
11281
Jeff Johnson295189b2012-06-20 16:38:30 -070011282 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011283 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011284 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011285 status = -EOPNOTSUPP;
11286 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011287 }
11288
11289 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11290 __func__, setKey.encType);
11291
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011292 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011293#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11294 (!pairwise)
11295#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011296 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011297#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011298 )
11299 {
11300 /* set group key*/
11301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11302 "%s- %d: setting Broadcast key",
11303 __func__, __LINE__);
11304 setKey.keyDirection = eSIR_RX_ONLY;
11305 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11306 }
11307 else
11308 {
11309 /* set pairwise key*/
11310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11311 "%s- %d: setting pairwise key",
11312 __func__, __LINE__);
11313 setKey.keyDirection = eSIR_TX_RX;
11314 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11315 }
11316 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11317 {
11318 setKey.keyDirection = eSIR_TX_RX;
11319 /*Set the group key*/
11320 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11321 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011322
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011323 if ( 0 != status )
11324 {
11325 hddLog(VOS_TRACE_LEVEL_ERROR,
11326 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011327 status = -EINVAL;
11328 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011329 }
11330 /*Save the keys here and call sme_RoamSetKey for setting
11331 the PTK after peer joins the IBSS network*/
11332 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11333 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011334 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011335 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011336 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11337 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11338 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011339 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011340 if( pHostapdState->bssState == BSS_START )
11341 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011342 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11343 vos_status = wlan_hdd_check_ula_done(pAdapter);
11344
11345 if ( vos_status != VOS_STATUS_SUCCESS )
11346 {
11347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11348 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11349 __LINE__, vos_status );
11350
11351 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11352
11353 status = -EINVAL;
11354 goto end;
11355 }
11356
Jeff Johnson295189b2012-06-20 16:38:30 -070011357 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11358
11359 if ( status != eHAL_STATUS_SUCCESS )
11360 {
11361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11362 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11363 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011364 status = -EINVAL;
11365 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011366 }
11367 }
11368
11369 /* Saving WEP keys */
11370 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11371 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11372 {
11373 //Save the wep key in ap context. Issue setkey after the BSS is started.
11374 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11375 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11376 }
11377 else
11378 {
11379 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011380 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011381 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11382 }
11383 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011384 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11385 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011386 {
11387 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11388 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11389
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011390#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11391 if (!pairwise)
11392#else
11393 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11394#endif
11395 {
11396 /* set group key*/
11397 if (pHddStaCtx->roam_info.deferKeyComplete)
11398 {
11399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11400 "%s- %d: Perform Set key Complete",
11401 __func__, __LINE__);
11402 hdd_PerformRoamSetKeyComplete(pAdapter);
11403 }
11404 }
11405
Jeff Johnson295189b2012-06-20 16:38:30 -070011406 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11407
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011408 pWextState->roamProfile.Keys.defaultIndex = key_index;
11409
11410
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011411 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011412 params->key, params->key_len);
11413
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011414
Jeff Johnson295189b2012-06-20 16:38:30 -070011415 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11416
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011417 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011418 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011419 __func__, setKey.peerMac[0], setKey.peerMac[1],
11420 setKey.peerMac[2], setKey.peerMac[3],
11421 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011422 setKey.keyDirection);
11423
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011424 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011425
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011426 if ( vos_status != VOS_STATUS_SUCCESS )
11427 {
11428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011429 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11430 __LINE__, vos_status );
11431
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011432 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011433
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011434 status = -EINVAL;
11435 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011436
11437 }
11438
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011439#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011440 /* The supplicant may attempt to set the PTK once pre-authentication
11441 is done. Save the key in the UMAC and include it in the ADD BSS
11442 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011443 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011444 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011445 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011446 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11447 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011448 status = 0;
11449 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011450 }
11451 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11452 {
11453 hddLog(VOS_TRACE_LEVEL_ERROR,
11454 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011455 status = -EINVAL;
11456 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011457 }
11458#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011459
11460 /* issue set key request to SME*/
11461 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11462 pAdapter->sessionId, &setKey, &roamId );
11463
11464 if ( 0 != status )
11465 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011466 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011467 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11468 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011469 status = -EINVAL;
11470 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011471 }
11472
11473
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011474 /* in case of IBSS as there was no information available about WEP keys during
11475 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011476 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011477 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11478 !( ( IW_AUTH_KEY_MGMT_802_1X
11479 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011480 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11481 )
11482 &&
11483 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11484 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11485 )
11486 )
11487 {
11488 setKey.keyDirection = eSIR_RX_ONLY;
11489 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11490
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011491 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011492 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011493 __func__, setKey.peerMac[0], setKey.peerMac[1],
11494 setKey.peerMac[2], setKey.peerMac[3],
11495 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011496 setKey.keyDirection);
11497
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011498 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011499 pAdapter->sessionId, &setKey, &roamId );
11500
11501 if ( 0 != status )
11502 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011503 hddLog(VOS_TRACE_LEVEL_ERROR,
11504 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011505 __func__, status);
11506 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011507 status = -EINVAL;
11508 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011509 }
11510 }
11511 }
11512
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011513end:
11514 /* Need to clear any trace of key value in the memory.
11515 * Thus zero out the memory even though it is local
11516 * variable.
11517 */
11518 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011519 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011520 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011521}
11522
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011523#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11524static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11525 struct net_device *ndev,
11526 u8 key_index, bool pairwise,
11527 const u8 *mac_addr,
11528 struct key_params *params
11529 )
11530#else
11531static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11532 struct net_device *ndev,
11533 u8 key_index, const u8 *mac_addr,
11534 struct key_params *params
11535 )
11536#endif
11537{
11538 int ret;
11539 vos_ssr_protect(__func__);
11540#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11541 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11542 mac_addr, params);
11543#else
11544 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11545 params);
11546#endif
11547 vos_ssr_unprotect(__func__);
11548
11549 return ret;
11550}
11551
Jeff Johnson295189b2012-06-20 16:38:30 -070011552/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011553 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011554 * This function is used to get the key information
11555 */
11556#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011557static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011558 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011559 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011560 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011561 const u8 *mac_addr, void *cookie,
11562 void (*callback)(void *cookie, struct key_params*)
11563 )
11564#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011565static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011566 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011567 struct net_device *ndev,
11568 u8 key_index, const u8 *mac_addr, void *cookie,
11569 void (*callback)(void *cookie, struct key_params*)
11570 )
11571#endif
11572{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011573 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011574 hdd_wext_state_t *pWextState = NULL;
11575 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011576 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011577 hdd_context_t *pHddCtx;
11578 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011579
11580 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011581
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011582 if (NULL == pAdapter)
11583 {
11584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11585 "%s: HDD adapter is Null", __func__);
11586 return -ENODEV;
11587 }
11588
11589 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11590 ret = wlan_hdd_validate_context(pHddCtx);
11591 if (0 != ret)
11592 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011593 return ret;
11594 }
11595
11596 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11597 pRoamProfile = &(pWextState->roamProfile);
11598
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011599 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11600 __func__, hdd_device_modetoString(pAdapter->device_mode),
11601 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011602
Jeff Johnson295189b2012-06-20 16:38:30 -070011603 memset(&params, 0, sizeof(params));
11604
11605 if (CSR_MAX_NUM_KEY <= key_index)
11606 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011607 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011608 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011609 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011610
11611 switch(pRoamProfile->EncryptionType.encryptionType[0])
11612 {
11613 case eCSR_ENCRYPT_TYPE_NONE:
11614 params.cipher = IW_AUTH_CIPHER_NONE;
11615 break;
11616
11617 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11618 case eCSR_ENCRYPT_TYPE_WEP40:
11619 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11620 break;
11621
11622 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11623 case eCSR_ENCRYPT_TYPE_WEP104:
11624 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11625 break;
11626
11627 case eCSR_ENCRYPT_TYPE_TKIP:
11628 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11629 break;
11630
11631 case eCSR_ENCRYPT_TYPE_AES:
11632 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11633 break;
11634
11635 default:
11636 params.cipher = IW_AUTH_CIPHER_NONE;
11637 break;
11638 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011639
c_hpothuaaf19692014-05-17 17:01:48 +053011640 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11641 TRACE_CODE_HDD_CFG80211_GET_KEY,
11642 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011643
Jeff Johnson295189b2012-06-20 16:38:30 -070011644 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11645 params.seq_len = 0;
11646 params.seq = NULL;
11647 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11648 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011649 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011650 return 0;
11651}
11652
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011653#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11654static int wlan_hdd_cfg80211_get_key(
11655 struct wiphy *wiphy,
11656 struct net_device *ndev,
11657 u8 key_index, bool pairwise,
11658 const u8 *mac_addr, void *cookie,
11659 void (*callback)(void *cookie, struct key_params*)
11660 )
11661#else
11662static int wlan_hdd_cfg80211_get_key(
11663 struct wiphy *wiphy,
11664 struct net_device *ndev,
11665 u8 key_index, const u8 *mac_addr, void *cookie,
11666 void (*callback)(void *cookie, struct key_params*)
11667 )
11668#endif
11669{
11670 int ret;
11671
11672 vos_ssr_protect(__func__);
11673#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11674 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
11675 mac_addr, cookie, callback);
11676#else
11677 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
11678 callback);
11679#endif
11680 vos_ssr_unprotect(__func__);
11681
11682 return ret;
11683}
11684
Jeff Johnson295189b2012-06-20 16:38:30 -070011685/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011686 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011687 * This function is used to delete the key information
11688 */
11689#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011690static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011691 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011692 u8 key_index,
11693 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011694 const u8 *mac_addr
11695 )
11696#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011697static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011698 struct net_device *ndev,
11699 u8 key_index,
11700 const u8 *mac_addr
11701 )
11702#endif
11703{
11704 int status = 0;
11705
11706 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011707 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070011708 //it is observed that this is invalidating peer
11709 //key index whenever re-key is done. This is affecting data link.
11710 //It should be ok to ignore del_key.
11711#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011712 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
11713 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011714 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11715 tCsrRoamSetKey setKey;
11716 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011717
Jeff Johnson295189b2012-06-20 16:38:30 -070011718 ENTER();
11719
11720 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
11721 __func__,pAdapter->device_mode);
11722
11723 if (CSR_MAX_NUM_KEY <= key_index)
11724 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011725 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011726 key_index);
11727
11728 return -EINVAL;
11729 }
11730
11731 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11732 setKey.keyId = key_index;
11733
11734 if (mac_addr)
11735 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11736 else
11737 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
11738
11739 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
11740
11741 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011742 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011743 )
11744 {
11745
11746 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070011747 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11748 if( pHostapdState->bssState == BSS_START)
11749 {
11750 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011751
Jeff Johnson295189b2012-06-20 16:38:30 -070011752 if ( status != eHAL_STATUS_SUCCESS )
11753 {
11754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11755 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11756 __LINE__, status );
11757 }
11758 }
11759 }
11760 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011761 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070011762 )
11763 {
11764 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11765
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011766 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11767
11768 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011769 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011770 __func__, setKey.peerMac[0], setKey.peerMac[1],
11771 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070011772 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011773 if(pAdapter->sessionCtx.station.conn_info.connState ==
11774 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070011775 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011776 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011777 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011778
Jeff Johnson295189b2012-06-20 16:38:30 -070011779 if ( 0 != status )
11780 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011781 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011782 "%s: sme_RoamSetKey failure, returned %d",
11783 __func__, status);
11784 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11785 return -EINVAL;
11786 }
11787 }
11788 }
11789#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011790 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011791 return status;
11792}
11793
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011794#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11795static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11796 struct net_device *ndev,
11797 u8 key_index,
11798 bool pairwise,
11799 const u8 *mac_addr
11800 )
11801#else
11802static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11803 struct net_device *ndev,
11804 u8 key_index,
11805 const u8 *mac_addr
11806 )
11807#endif
11808{
11809 int ret;
11810
11811 vos_ssr_protect(__func__);
11812#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11813 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
11814 mac_addr);
11815#else
11816 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
11817#endif
11818 vos_ssr_unprotect(__func__);
11819
11820 return ret;
11821}
11822
Jeff Johnson295189b2012-06-20 16:38:30 -070011823/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011824 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011825 * This function is used to set the default tx key index
11826 */
11827#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011828static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011829 struct net_device *ndev,
11830 u8 key_index,
11831 bool unicast, bool multicast)
11832#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011833static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011834 struct net_device *ndev,
11835 u8 key_index)
11836#endif
11837{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011838 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011839 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011840 hdd_wext_state_t *pWextState;
11841 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011842 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011843
11844 ENTER();
11845
Gopichand Nakkala29149562013-05-10 21:43:41 +053011846 if ((NULL == pAdapter))
11847 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011849 "invalid adapter");
11850 return -EINVAL;
11851 }
11852
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011853 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11854 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
11855 pAdapter->sessionId, key_index));
11856
Gopichand Nakkala29149562013-05-10 21:43:41 +053011857 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11858 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11859
11860 if ((NULL == pWextState) || (NULL == pHddStaCtx))
11861 {
11862 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11863 "invalid Wext state or HDD context");
11864 return -EINVAL;
11865 }
11866
Arif Hussain6d2a3322013-11-17 19:50:10 -080011867 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011868 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011869
Jeff Johnson295189b2012-06-20 16:38:30 -070011870 if (CSR_MAX_NUM_KEY <= key_index)
11871 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011872 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011873 key_index);
11874
11875 return -EINVAL;
11876 }
11877
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011878 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11879 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011880 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011881 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011882 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011883 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011884
Jeff Johnson295189b2012-06-20 16:38:30 -070011885 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011886 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011887 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011888 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011889 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080011890 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011891 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080011892 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070011893 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011894 {
11895 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070011896 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011897
Jeff Johnson295189b2012-06-20 16:38:30 -070011898 tCsrRoamSetKey setKey;
11899 v_U32_t roamId= 0xFF;
11900 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011901
11902 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011903 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011904
Jeff Johnson295189b2012-06-20 16:38:30 -070011905 Keys->defaultIndex = (u8)key_index;
11906 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11907 setKey.keyId = key_index;
11908 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011909
11910 vos_mem_copy(&setKey.Key[0],
11911 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011912 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011913
Gopichand Nakkala29149562013-05-10 21:43:41 +053011914 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011915
11916 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070011917 &pHddStaCtx->conn_info.bssId[0],
11918 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011919
Gopichand Nakkala29149562013-05-10 21:43:41 +053011920 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
11921 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
11922 eCSR_ENCRYPT_TYPE_WEP104)
11923 {
11924 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
11925 even though ap is configured for WEP-40 encryption. In this canse the key length
11926 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
11927 type(104) and switching encryption type to 40*/
11928 pWextState->roamProfile.EncryptionType.encryptionType[0] =
11929 eCSR_ENCRYPT_TYPE_WEP40;
11930 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
11931 eCSR_ENCRYPT_TYPE_WEP40;
11932 }
11933
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011934 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011935 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011936
Jeff Johnson295189b2012-06-20 16:38:30 -070011937 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011938 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011939 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011940
Jeff Johnson295189b2012-06-20 16:38:30 -070011941 if ( 0 != status )
11942 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011943 hddLog(VOS_TRACE_LEVEL_ERROR,
11944 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011945 status);
11946 return -EINVAL;
11947 }
11948 }
11949 }
11950
11951 /* In SoftAp mode setting key direction for default mode */
11952 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
11953 {
11954 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
11955 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
11956 (eCSR_ENCRYPT_TYPE_AES !=
11957 pWextState->roamProfile.EncryptionType.encryptionType[0])
11958 )
11959 {
11960 /* Saving key direction for default key index to TX default */
11961 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11962 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
11963 }
11964 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011965 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011966 return status;
11967}
11968
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011969#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11970static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11971 struct net_device *ndev,
11972 u8 key_index,
11973 bool unicast, bool multicast)
11974#else
11975static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11976 struct net_device *ndev,
11977 u8 key_index)
11978#endif
11979{
11980 int ret;
11981 vos_ssr_protect(__func__);
11982#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11983 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
11984 multicast);
11985#else
11986 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
11987#endif
11988 vos_ssr_unprotect(__func__);
11989
11990 return ret;
11991}
11992
Jeff Johnson295189b2012-06-20 16:38:30 -070011993/*
11994 * FUNCTION: wlan_hdd_cfg80211_inform_bss
11995 * This function is used to inform the BSS details to nl80211 interface.
11996 */
11997static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
11998 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
11999{
12000 struct net_device *dev = pAdapter->dev;
12001 struct wireless_dev *wdev = dev->ieee80211_ptr;
12002 struct wiphy *wiphy = wdev->wiphy;
12003 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12004 int chan_no;
12005 int ie_length;
12006 const char *ie;
12007 unsigned int freq;
12008 struct ieee80211_channel *chan;
12009 int rssi = 0;
12010 struct cfg80211_bss *bss = NULL;
12011
Jeff Johnson295189b2012-06-20 16:38:30 -070012012 if( NULL == pBssDesc )
12013 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012014 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012015 return bss;
12016 }
12017
12018 chan_no = pBssDesc->channelId;
12019 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12020 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12021
12022 if( NULL == ie )
12023 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012024 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012025 return bss;
12026 }
12027
12028#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12029 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12030 {
12031 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12032 }
12033 else
12034 {
12035 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12036 }
12037#else
12038 freq = ieee80211_channel_to_frequency(chan_no);
12039#endif
12040
12041 chan = __ieee80211_get_channel(wiphy, freq);
12042
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012043 if (!chan) {
12044 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12045 return NULL;
12046 }
12047
Abhishek Singhaee43942014-06-16 18:55:47 +053012048 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012049
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012050 return cfg80211_inform_bss(wiphy, chan,
12051#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12052 CFG80211_BSS_FTYPE_UNKNOWN,
12053#endif
12054 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012055 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012056 pBssDesc->capabilityInfo,
12057 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012058 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012059}
12060
12061
12062
12063/*
12064 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12065 * This function is used to inform the BSS details to nl80211 interface.
12066 */
12067struct cfg80211_bss*
12068wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12069 tSirBssDescription *bss_desc
12070 )
12071{
12072 /*
12073 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12074 already exists in bss data base of cfg80211 for that particular BSS ID.
12075 Using cfg80211_inform_bss_frame to update the bss entry instead of
12076 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12077 now there is no possibility to get the mgmt(probe response) frame from PE,
12078 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12079 cfg80211_inform_bss_frame.
12080 */
12081 struct net_device *dev = pAdapter->dev;
12082 struct wireless_dev *wdev = dev->ieee80211_ptr;
12083 struct wiphy *wiphy = wdev->wiphy;
12084 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012085#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12086 qcom_ie_age *qie_age = NULL;
12087 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12088#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012089 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012090#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012091 const char *ie =
12092 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12093 unsigned int freq;
12094 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012095 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012096 struct cfg80211_bss *bss_status = NULL;
12097 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12098 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012099 hdd_context_t *pHddCtx;
12100 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012101#ifdef WLAN_OPEN_SOURCE
12102 struct timespec ts;
12103#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012104
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012105
Wilson Yangf80a0542013-10-07 13:02:37 -070012106 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12107 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012108 if (0 != status)
12109 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012110 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012111 }
12112
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012113 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012114 if (!mgmt)
12115 {
12116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12117 "%s: memory allocation failed ", __func__);
12118 return NULL;
12119 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012120
Jeff Johnson295189b2012-06-20 16:38:30 -070012121 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012122
12123#ifdef WLAN_OPEN_SOURCE
12124 /* Android does not want the timestamp from the frame.
12125 Instead it wants a monotonic increasing value */
12126 get_monotonic_boottime(&ts);
12127 mgmt->u.probe_resp.timestamp =
12128 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12129#else
12130 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012131 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12132 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012133
12134#endif
12135
Jeff Johnson295189b2012-06-20 16:38:30 -070012136 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12137 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012138
12139#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12140 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12141 /* Assuming this is the last IE, copy at the end */
12142 ie_length -=sizeof(qcom_ie_age);
12143 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12144 qie_age->element_id = QCOM_VENDOR_IE_ID;
12145 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12146 qie_age->oui_1 = QCOM_OUI1;
12147 qie_age->oui_2 = QCOM_OUI2;
12148 qie_age->oui_3 = QCOM_OUI3;
12149 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
12150 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
12151#endif
12152
Jeff Johnson295189b2012-06-20 16:38:30 -070012153 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012154 if (bss_desc->fProbeRsp)
12155 {
12156 mgmt->frame_control |=
12157 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12158 }
12159 else
12160 {
12161 mgmt->frame_control |=
12162 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12163 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012164
12165#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012166 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012167 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12168 {
12169 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12170 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012171 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012172 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12173
12174 {
12175 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12176 }
12177 else
12178 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012179 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12180 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012181 kfree(mgmt);
12182 return NULL;
12183 }
12184#else
12185 freq = ieee80211_channel_to_frequency(chan_no);
12186#endif
12187 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012188 /*when the band is changed on the fly using the GUI, three things are done
12189 * 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)
12190 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12191 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12192 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12193 * and discards the channels correponding to previous band and calls back with zero bss results.
12194 * 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
12195 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12196 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12197 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12198 * So drop the bss and continue to next bss.
12199 */
12200 if(chan == NULL)
12201 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012202 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070012203 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012204 return NULL;
12205 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012206 /*To keep the rssi icon of the connected AP in the scan window
12207 *and the rssi icon of the wireless networks in sync
12208 * */
12209 if (( eConnectionState_Associated ==
12210 pAdapter->sessionCtx.station.conn_info.connState ) &&
12211 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12212 pAdapter->sessionCtx.station.conn_info.bssId,
12213 WNI_CFG_BSSID_LEN)) &&
12214 (pHddCtx->hdd_wlan_suspended == FALSE))
12215 {
12216 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12217 rssi = (pAdapter->rssi * 100);
12218 }
12219 else
12220 {
12221 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12222 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012223
Nirav Shah20ac06f2013-12-12 18:14:06 +053012224 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012225 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12226 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012227
Jeff Johnson295189b2012-06-20 16:38:30 -070012228 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12229 frame_len, rssi, GFP_KERNEL);
12230 kfree(mgmt);
12231 return bss_status;
12232}
12233
12234/*
12235 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12236 * This function is used to update the BSS data base of CFG8011
12237 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012238struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012239 tCsrRoamInfo *pRoamInfo
12240 )
12241{
12242 tCsrRoamConnectedProfile roamProfile;
12243 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12244 struct cfg80211_bss *bss = NULL;
12245
12246 ENTER();
12247
12248 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12249 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12250
12251 if (NULL != roamProfile.pBssDesc)
12252 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012253 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12254 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012255
12256 if (NULL == bss)
12257 {
12258 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12259 __func__);
12260 }
12261
12262 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12263 }
12264 else
12265 {
12266 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12267 __func__);
12268 }
12269 return bss;
12270}
12271
12272/*
12273 * FUNCTION: wlan_hdd_cfg80211_update_bss
12274 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012275static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12276 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012277 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012278{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012279 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012280 tCsrScanResultInfo *pScanResult;
12281 eHalStatus status = 0;
12282 tScanResultHandle pResult;
12283 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012284 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012285 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012286 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012287
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012288 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12289 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12290 NO_SESSION, pAdapter->sessionId));
12291
Wilson Yangf80a0542013-10-07 13:02:37 -070012292 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12293
12294 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070012295 {
Wilson Yangf80a0542013-10-07 13:02:37 -070012296 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12297 "%s:LOGP in Progress. Ignore!!!",__func__);
12298 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070012299 }
12300
Wilson Yangf80a0542013-10-07 13:02:37 -070012301
12302 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053012303 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070012304 {
12305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12306 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
12307 return VOS_STATUS_E_PERM;
12308 }
12309
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012310 if (pAdapter->request != NULL)
12311 {
12312 if ((pAdapter->request->n_ssids == 1)
12313 && (pAdapter->request->ssids != NULL)
12314 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12315 is_p2p_scan = true;
12316 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012317 /*
12318 * start getting scan results and populate cgf80211 BSS database
12319 */
12320 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12321
12322 /* no scan results */
12323 if (NULL == pResult)
12324 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012325 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12326 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012327 wlan_hdd_get_frame_logs(pAdapter,
12328 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012329 return status;
12330 }
12331
12332 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12333
12334 while (pScanResult)
12335 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012336 /*
12337 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12338 * entry already exists in bss data base of cfg80211 for that
12339 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12340 * bss entry instead of cfg80211_inform_bss, But this call expects
12341 * mgmt packet as input. As of now there is no possibility to get
12342 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012343 * ieee80211_mgmt(probe response) and passing to c
12344 * fg80211_inform_bss_frame.
12345 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012346 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12347 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12348 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012349 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12350 continue; //Skip the non p2p bss entries
12351 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012352 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12353 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012354
Jeff Johnson295189b2012-06-20 16:38:30 -070012355
12356 if (NULL == bss_status)
12357 {
12358 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012359 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012360 }
12361 else
12362 {
Yue Maf49ba872013-08-19 12:04:25 -070012363 cfg80211_put_bss(
12364#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12365 wiphy,
12366#endif
12367 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012368 }
12369
12370 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12371 }
12372
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012373 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012374 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012375 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012376}
12377
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012378void
12379hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12380{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012381 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012382 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012383} /****** end hddPrintMacAddr() ******/
12384
12385void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012386hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012387{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012388 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012389 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012390 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12391 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12392 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012393} /****** end hddPrintPmkId() ******/
12394
12395//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12396//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12397
12398//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12399//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12400
12401#define dump_bssid(bssid) \
12402 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012403 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12404 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012405 }
12406
12407#define dump_pmkid(pMac, pmkid) \
12408 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012409 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12410 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012411 }
12412
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012413#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012414/*
12415 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12416 * This function is used to notify the supplicant of a new PMKSA candidate.
12417 */
12418int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012419 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012420 int index, bool preauth )
12421{
Jeff Johnsone7245742012-09-05 17:12:55 -070012422#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012423 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012424 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012425
12426 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012427 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012428
12429 if( NULL == pRoamInfo )
12430 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012431 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012432 return -EINVAL;
12433 }
12434
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012435 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12436 {
12437 dump_bssid(pRoamInfo->bssid);
12438 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012439 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012440 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012441#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012442 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012443}
12444#endif //FEATURE_WLAN_LFR
12445
Yue Maef608272013-04-08 23:09:17 -070012446#ifdef FEATURE_WLAN_LFR_METRICS
12447/*
12448 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12449 * 802.11r/LFR metrics reporting function to report preauth initiation
12450 *
12451 */
12452#define MAX_LFR_METRICS_EVENT_LENGTH 100
12453VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12454 tCsrRoamInfo *pRoamInfo)
12455{
12456 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12457 union iwreq_data wrqu;
12458
12459 ENTER();
12460
12461 if (NULL == pAdapter)
12462 {
12463 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12464 return VOS_STATUS_E_FAILURE;
12465 }
12466
12467 /* create the event */
12468 memset(&wrqu, 0, sizeof(wrqu));
12469 memset(metrics_notification, 0, sizeof(metrics_notification));
12470
12471 wrqu.data.pointer = metrics_notification;
12472 wrqu.data.length = scnprintf(metrics_notification,
12473 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12474 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12475
12476 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12477
12478 EXIT();
12479
12480 return VOS_STATUS_SUCCESS;
12481}
12482
12483/*
12484 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12485 * 802.11r/LFR metrics reporting function to report preauth completion
12486 * or failure
12487 */
12488VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12489 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12490{
12491 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12492 union iwreq_data wrqu;
12493
12494 ENTER();
12495
12496 if (NULL == pAdapter)
12497 {
12498 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12499 return VOS_STATUS_E_FAILURE;
12500 }
12501
12502 /* create the event */
12503 memset(&wrqu, 0, sizeof(wrqu));
12504 memset(metrics_notification, 0, sizeof(metrics_notification));
12505
12506 scnprintf(metrics_notification, sizeof(metrics_notification),
12507 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12508 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12509
12510 if (1 == preauth_status)
12511 strncat(metrics_notification, " TRUE", 5);
12512 else
12513 strncat(metrics_notification, " FALSE", 6);
12514
12515 wrqu.data.pointer = metrics_notification;
12516 wrqu.data.length = strlen(metrics_notification);
12517
12518 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12519
12520 EXIT();
12521
12522 return VOS_STATUS_SUCCESS;
12523}
12524
12525/*
12526 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12527 * 802.11r/LFR metrics reporting function to report handover initiation
12528 *
12529 */
12530VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12531 tCsrRoamInfo *pRoamInfo)
12532{
12533 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12534 union iwreq_data wrqu;
12535
12536 ENTER();
12537
12538 if (NULL == pAdapter)
12539 {
12540 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12541 return VOS_STATUS_E_FAILURE;
12542 }
12543
12544 /* create the event */
12545 memset(&wrqu, 0, sizeof(wrqu));
12546 memset(metrics_notification, 0, sizeof(metrics_notification));
12547
12548 wrqu.data.pointer = metrics_notification;
12549 wrqu.data.length = scnprintf(metrics_notification,
12550 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12551 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12552
12553 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12554
12555 EXIT();
12556
12557 return VOS_STATUS_SUCCESS;
12558}
12559#endif
12560
Jeff Johnson295189b2012-06-20 16:38:30 -070012561/*
12562 * FUNCTION: hdd_cfg80211_scan_done_callback
12563 * scanning callback function, called after finishing scan
12564 *
12565 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012566static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012567 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12568{
12569 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012570 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012571 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012572 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012573 struct cfg80211_scan_request *req = NULL;
12574 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012575 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012576 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012577 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012578 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012579
12580 ENTER();
12581
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012582 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012583 if (NULL == pHddCtx) {
12584 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012585 goto allow_suspend;
12586 }
12587
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012588#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12589 if (!(pAdapter->dev->flags & IFF_UP))
12590 {
12591 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
12592 goto allow_suspend;
12593 }
12594#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012595 pScanInfo = &pHddCtx->scan_info;
12596
Jeff Johnson295189b2012-06-20 16:38:30 -070012597 hddLog(VOS_TRACE_LEVEL_INFO,
12598 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012599 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012600 __func__, halHandle, pContext, (int) scanId, (int) status);
12601
Kiet Lamac06e2c2013-10-23 16:25:07 +053012602 pScanInfo->mScanPendingCounter = 0;
12603
Jeff Johnson295189b2012-06-20 16:38:30 -070012604 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012605 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012606 &pScanInfo->scan_req_completion_event,
12607 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012608 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012609 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012610 hddLog(VOS_TRACE_LEVEL_ERROR,
12611 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012612 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012613 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012614 }
12615
Yue Maef608272013-04-08 23:09:17 -070012616 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012617 {
12618 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012619 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012620 }
12621
12622 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012623 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012624 {
12625 hddLog(VOS_TRACE_LEVEL_INFO,
12626 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012627 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012628 (int) scanId);
12629 }
12630
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012631 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012632 pAdapter);
12633
12634 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012635 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012636
12637
12638 /* If any client wait scan result through WEXT
12639 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012640 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012641 {
12642 /* The other scan request waiting for current scan finish
12643 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012644 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012645 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012646 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012647 }
12648 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012649 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012650 {
12651 struct net_device *dev = pAdapter->dev;
12652 union iwreq_data wrqu;
12653 int we_event;
12654 char *msg;
12655
12656 memset(&wrqu, '\0', sizeof(wrqu));
12657 we_event = SIOCGIWSCAN;
12658 msg = NULL;
12659 wireless_send_event(dev, we_event, &wrqu, msg);
12660 }
12661 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012662 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012663
12664 /* Get the Scan Req */
12665 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053012666 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012667
mukul sharmae7041822015-12-03 15:09:21 +053012668 if (!req || req->wiphy == NULL)
Jeff Johnson295189b2012-06-20 16:38:30 -070012669 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012670 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012671 pScanInfo->mScanPending = VOS_FALSE;
mukul sharmae7041822015-12-03 15:09:21 +053012672 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070012673 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012674 }
12675
Jeff Johnson295189b2012-06-20 16:38:30 -070012676 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070012677 /* Scan is no longer pending */
12678 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012679
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012680 /* last_scan_timestamp is used to decide if new scan
12681 * is needed or not on station interface. If last station
12682 * scan time and new station scan time is less then
12683 * last_scan_timestamp ; driver will return cached scan.
12684 */
12685 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12686 {
12687 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12688
12689 if ( req->n_channels )
12690 {
12691 for (i = 0; i < req->n_channels ; i++ )
12692 {
12693 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12694 }
12695 /* store no of channel scanned */
12696 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
12697 }
12698
12699 }
12700
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070012701 /*
12702 * cfg80211_scan_done informing NL80211 about completion
12703 * of scanning
12704 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012705 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
12706 {
12707 aborted = true;
12708 }
mukul sharmae7041822015-12-03 15:09:21 +053012709
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012710 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053012711
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012712 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070012713
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053012714 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
12715 ) && (pHddCtx->spoofMacAddr.isEnabled
12716 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053012717 /* Generate new random mac addr for next scan */
12718 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053012719
12720 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
12721 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053012722 }
12723
Jeff Johnsone7245742012-09-05 17:12:55 -070012724allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012725 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012726 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012727
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012728 /* Acquire wakelock to handle the case where APP's tries to suspend
12729 * immediatly after the driver gets connect request(i.e after scan)
12730 * from supplicant, this result in app's is suspending and not able
12731 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012732 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012733
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012734#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053012735 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012736#endif
12737
Jeff Johnson295189b2012-06-20 16:38:30 -070012738 EXIT();
12739 return 0;
12740}
12741
12742/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053012743 * FUNCTION: hdd_isConnectionInProgress
12744 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012745 *
12746 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012747v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012748{
12749 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12750 hdd_station_ctx_t *pHddStaCtx = NULL;
12751 hdd_adapter_t *pAdapter = NULL;
12752 VOS_STATUS status = 0;
12753 v_U8_t staId = 0;
12754 v_U8_t *staMac = NULL;
12755
c_hpothu9b781ba2013-12-30 20:57:45 +053012756 if (TRUE == pHddCtx->btCoexModeSet)
12757 {
12758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053012759 FL("BTCoex Mode operation in progress"));
12760 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053012761 }
12762
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012763 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12764
12765 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12766 {
12767 pAdapter = pAdapterNode->pAdapter;
12768
12769 if( pAdapter )
12770 {
12771 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012772 "%s: Adapter with device mode %s (%d) exists",
12773 __func__, hdd_device_modetoString(pAdapter->device_mode),
12774 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012775 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053012776 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12777 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
12778 (eConnectionState_Connecting ==
12779 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12780 {
12781 hddLog(VOS_TRACE_LEVEL_ERROR,
12782 "%s: %p(%d) Connection is in progress", __func__,
12783 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12784 return VOS_TRUE;
12785 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012786 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053012787 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012788 {
12789 hddLog(VOS_TRACE_LEVEL_ERROR,
12790 "%s: %p(%d) Reassociation is in progress", __func__,
12791 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12792 return VOS_TRUE;
12793 }
12794 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012795 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12796 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012797 {
12798 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12799 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012800 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012801 {
12802 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
12803 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012804 "%s: client " MAC_ADDRESS_STR
12805 " is in the middle of WPS/EAPOL exchange.", __func__,
12806 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012807 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012808 }
12809 }
12810 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
12811 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
12812 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012813 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12814 ptSapContext pSapCtx = NULL;
12815 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12816 if(pSapCtx == NULL){
12817 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12818 FL("psapCtx is NULL"));
12819 return VOS_FALSE;
12820 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012821 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
12822 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012823 if ((pSapCtx->aStaInfo[staId].isUsed) &&
12824 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012825 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012826 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012827
12828 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012829 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
12830 "middle of WPS/EAPOL exchange.", __func__,
12831 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012832 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012833 }
12834 }
12835 }
12836 }
12837 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12838 pAdapterNode = pNext;
12839 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053012840 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012841}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012842
12843/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012844 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070012845 * this scan respond to scan trigger and update cfg80211 scan database
12846 * later, scan dump command can be used to recieve scan results
12847 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012848int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080012849#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12850 struct net_device *dev,
12851#endif
12852 struct cfg80211_scan_request *request)
12853{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012854 hdd_adapter_t *pAdapter = NULL;
12855 hdd_context_t *pHddCtx = NULL;
12856 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012857 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012858 tCsrScanRequest scanRequest;
12859 tANI_U8 *channelList = NULL, i;
12860 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012861 int status;
12862 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012863 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012864 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053012865 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053012866 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012867 v_S7_t rssi=0;
12868 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012869
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012870#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
12871 struct net_device *dev = NULL;
12872 if (NULL == request)
12873 {
12874 hddLog(VOS_TRACE_LEVEL_ERROR,
12875 "%s: scan req param null", __func__);
12876 return -EINVAL;
12877 }
12878 dev = request->wdev->netdev;
12879#endif
12880
12881 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12882 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
12883 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12884
Jeff Johnson295189b2012-06-20 16:38:30 -070012885 ENTER();
12886
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012887 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12888 __func__, hdd_device_modetoString(pAdapter->device_mode),
12889 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012890
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012891 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012892 if (0 != status)
12893 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012894 return status;
12895 }
12896
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012897 if (NULL == pwextBuf)
12898 {
12899 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
12900 __func__);
12901 return -EIO;
12902 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012903 cfg_param = pHddCtx->cfg_ini;
12904 pScanInfo = &pHddCtx->scan_info;
12905
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012906 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12907 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
12908 {
12909 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
12910 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
12911 }
12912
Jeff Johnson295189b2012-06-20 16:38:30 -070012913#ifdef WLAN_BTAMP_FEATURE
12914 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012915 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070012916 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080012917 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012918 "%s: No scanning when AMP is on", __func__);
12919 return -EOPNOTSUPP;
12920 }
12921#endif
12922 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012923 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012924 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012925 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012926 "%s: Not scanning on device_mode = %s (%d)",
12927 __func__, hdd_device_modetoString(pAdapter->device_mode),
12928 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012929 return -EOPNOTSUPP;
12930 }
12931
12932 if (TRUE == pScanInfo->mScanPending)
12933 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012934 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
12935 {
12936 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
12937 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012938 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012939 }
12940
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053012941 // Don't allow scan if PNO scan is going on.
12942 if (pHddCtx->isPnoEnable)
12943 {
12944 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12945 FL("pno scan in progress"));
12946 return -EBUSY;
12947 }
12948
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012949 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070012950 //Channel and action frame is pending
12951 //Otherwise Cancel Remain On Channel and allow Scan
12952 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012953 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070012954 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012955 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070012956 return -EBUSY;
12957 }
12958
Jeff Johnson295189b2012-06-20 16:38:30 -070012959 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
12960 {
12961 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080012962 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012963 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012964 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012965 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
12966 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012967 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012968 "%s: MAX TM Level Scan not allowed", __func__);
12969 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012970 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012971 }
12972 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
12973
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012974 /* Check if scan is allowed at this point of time.
12975 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012976 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012977 {
12978 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
12979 return -EBUSY;
12980 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012981
Jeff Johnson295189b2012-06-20 16:38:30 -070012982 vos_mem_zero( &scanRequest, sizeof(scanRequest));
12983
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012984 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
12985 * Becasue of this, driver is assuming that this is not wildcard scan and so
12986 * is not aging out the scan results.
12987 */
12988 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070012989 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012990 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012991 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012992
12993 if ((request->ssids) && (0 < request->n_ssids))
12994 {
12995 tCsrSSIDInfo *SsidInfo;
12996 int j;
12997 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
12998 /* Allocate num_ssid tCsrSSIDInfo structure */
12999 SsidInfo = scanRequest.SSIDs.SSIDList =
13000 ( tCsrSSIDInfo *)vos_mem_malloc(
13001 request->n_ssids*sizeof(tCsrSSIDInfo));
13002
13003 if(NULL == scanRequest.SSIDs.SSIDList)
13004 {
13005 hddLog(VOS_TRACE_LEVEL_ERROR,
13006 "%s: memory alloc failed SSIDInfo buffer", __func__);
13007 return -ENOMEM;
13008 }
13009
13010 /* copy all the ssid's and their length */
13011 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
13012 {
13013 /* get the ssid length */
13014 SsidInfo->SSID.length = request->ssids[j].ssid_len;
13015 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
13016 SsidInfo->SSID.length);
13017 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
13018 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
13019 j, SsidInfo->SSID.ssId);
13020 }
13021 /* set the scan type to active */
13022 scanRequest.scanType = eSIR_ACTIVE_SCAN;
13023 }
13024 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013025 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013026 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13027 TRACE_CODE_HDD_CFG80211_SCAN,
13028 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070013029 /* set the scan type to active */
13030 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070013031 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013032 else
13033 {
13034 /*Set the scan type to default type, in this case it is ACTIVE*/
13035 scanRequest.scanType = pScanInfo->scan_mode;
13036 }
13037 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
13038 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070013039
13040 /* set BSSType to default type */
13041 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
13042
13043 /*TODO: scan the requested channels only*/
13044
13045 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013046 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070013047 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013048 hddLog(VOS_TRACE_LEVEL_WARN,
13049 "No of Scan Channels exceeded limit: %d", request->n_channels);
13050 request->n_channels = MAX_CHANNEL;
13051 }
13052
13053 hddLog(VOS_TRACE_LEVEL_INFO,
13054 "No of Scan Channels: %d", request->n_channels);
13055
13056
13057 if( request->n_channels )
13058 {
13059 char chList [(request->n_channels*5)+1];
13060 int len;
13061 channelList = vos_mem_malloc( request->n_channels );
13062 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053013063 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013064 hddLog(VOS_TRACE_LEVEL_ERROR,
13065 "%s: memory alloc failed channelList", __func__);
13066 status = -ENOMEM;
13067 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053013068 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013069
13070 for( i = 0, len = 0; i < request->n_channels ; i++ )
13071 {
13072 channelList[i] = request->channels[i]->hw_value;
13073 len += snprintf(chList+len, 5, "%d ", channelList[i]);
13074 }
13075
Nirav Shah20ac06f2013-12-12 18:14:06 +053013076 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013077 "Channel-List: %s ", chList);
13078 }
c_hpothu53512302014-04-15 18:49:53 +053013079
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013080 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13081 scanRequest.ChannelInfo.ChannelList = channelList;
13082
13083 /* set requestType to full scan */
13084 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13085
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013086 /* if there is back to back scan happening in driver with in
13087 * nDeferScanTimeInterval interval driver should defer new scan request
13088 * and should provide last cached scan results instead of new channel list.
13089 * This rule is not applicable if scan is p2p scan.
13090 * This condition will work only in case when last request no of channels
13091 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013092 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013093 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013094 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013095
Sushant Kaushik86592172015-04-27 16:35:03 +053013096 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13097 /* if wps ie is NULL , then only defer scan */
13098 if ( pWpsIe == NULL &&
13099 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013100 {
13101 if ( pScanInfo->last_scan_timestamp !=0 &&
13102 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13103 {
13104 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13105 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13106 vos_mem_compare(pScanInfo->last_scan_channelList,
13107 channelList, pScanInfo->last_scan_numChannels))
13108 {
13109 hddLog(VOS_TRACE_LEVEL_WARN,
13110 " New and old station scan time differ is less then %u",
13111 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13112
13113 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013114 pAdapter);
13115
Agarwal Ashish57e84372014-12-05 18:26:53 +053013116 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013117 "Return old cached scan as all channels and no of channels are same");
13118
Agarwal Ashish57e84372014-12-05 18:26:53 +053013119 if (0 > ret)
13120 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013121
Agarwal Ashish57e84372014-12-05 18:26:53 +053013122 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013123
13124 status = eHAL_STATUS_SUCCESS;
13125 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013126 }
13127 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013128 }
13129
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013130 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13131 * search (Flush on both full scan and social scan but not on single
13132 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13133 */
13134
13135 /* Supplicant does single channel scan after 8-way handshake
13136 * and in that case driver shoudnt flush scan results. If
13137 * driver flushes the scan results here and unfortunately if
13138 * the AP doesnt respond to our probe req then association
13139 * fails which is not desired
13140 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013141 if ((request->n_ssids == 1)
13142 && (request->ssids != NULL)
13143 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13144 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013145
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013146 if( is_p2p_scan ||
13147 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013148 {
13149 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13150 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13151 pAdapter->sessionId );
13152 }
13153
13154 if( request->ie_len )
13155 {
13156 /* save this for future association (join requires this) */
13157 /*TODO: Array needs to be converted to dynamic allocation,
13158 * as multiple ie.s can be sent in cfg80211_scan_request structure
13159 * CR 597966
13160 */
13161 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13162 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13163 pScanInfo->scanAddIE.length = request->ie_len;
13164
13165 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13166 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13167 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013168 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013169 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013170 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013171 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13172 memcpy( pwextBuf->roamProfile.addIEScan,
13173 request->ie, request->ie_len);
13174 }
13175 else
13176 {
13177 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13178 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013179 }
13180
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013181 }
13182 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13183 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13184
13185 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13186 request->ie_len);
13187 if (pP2pIe != NULL)
13188 {
13189#ifdef WLAN_FEATURE_P2P_DEBUG
13190 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13191 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13192 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013193 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013194 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13195 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13196 "Go nego completed to Connection is started");
13197 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13198 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013199 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013200 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13201 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013202 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013203 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13204 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13205 "Disconnected state to Connection is started");
13206 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13207 "for 4way Handshake");
13208 }
13209#endif
13210
13211 /* no_cck will be set during p2p find to disable 11b rates */
13212 if(TRUE == request->no_cck)
13213 {
13214 hddLog(VOS_TRACE_LEVEL_INFO,
13215 "%s: This is a P2P Search", __func__);
13216 scanRequest.p2pSearch = 1;
13217
13218 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013219 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013220 /* set requestType to P2P Discovery */
13221 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13222 }
13223
13224 /*
13225 Skip Dfs Channel in case of P2P Search
13226 if it is set in ini file
13227 */
13228 if(cfg_param->skipDfsChnlInP2pSearch)
13229 {
13230 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013231 }
13232 else
13233 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013234 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013235 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013236
Agarwal Ashish4f616132013-12-30 23:32:50 +053013237 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013238 }
13239 }
13240
13241 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13242
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013243#ifdef FEATURE_WLAN_TDLS
13244 /* if tdls disagree scan right now, return immediately.
13245 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13246 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13247 */
13248 status = wlan_hdd_tdls_scan_callback (pAdapter,
13249 wiphy,
13250#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13251 dev,
13252#endif
13253 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013254 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013255 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053013256 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013257 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13258 "scan rejected %d", __func__, status);
13259 else
13260 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13261 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013262 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053013263 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013264 }
13265#endif
13266
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013267 /* acquire the wakelock to avoid the apps suspend during the scan. To
13268 * address the following issues.
13269 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13270 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13271 * for long time, this result in apps running at full power for long time.
13272 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13273 * be stuck in full power because of resume BMPS
13274 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013275 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013276
Nirav Shah20ac06f2013-12-12 18:14:06 +053013277 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13278 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013279 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13280 scanRequest.requestType, scanRequest.scanType,
13281 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013282 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13283
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013284 if (pHddCtx->spoofMacAddr.isEnabled &&
13285 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013286 {
13287 hddLog(VOS_TRACE_LEVEL_INFO,
13288 "%s: MAC Spoofing enabled for current scan", __func__);
13289 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13290 * to fill TxBds for probe request during current scan
13291 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013292 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013293 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013294
13295 if(status != VOS_STATUS_SUCCESS)
13296 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013297 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013298 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013299#ifdef FEATURE_WLAN_TDLS
13300 wlan_hdd_tdls_scan_done_callback(pAdapter);
13301#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013302 goto free_mem;
13303 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013304 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013305 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013306 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013307 pAdapter->sessionId, &scanRequest, &scanId,
13308 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013309
Jeff Johnson295189b2012-06-20 16:38:30 -070013310 if (eHAL_STATUS_SUCCESS != status)
13311 {
13312 hddLog(VOS_TRACE_LEVEL_ERROR,
13313 "%s: sme_ScanRequest returned error %d", __func__, status);
13314 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013315 if(eHAL_STATUS_RESOURCES == status)
13316 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013317 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13318 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013319 status = -EBUSY;
13320 } else {
13321 status = -EIO;
13322 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013323 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013324
13325#ifdef FEATURE_WLAN_TDLS
13326 wlan_hdd_tdls_scan_done_callback(pAdapter);
13327#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013328 goto free_mem;
13329 }
13330
13331 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013332 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013333 pAdapter->request = request;
13334 pScanInfo->scanId = scanId;
13335
13336 complete(&pScanInfo->scan_req_completion_event);
13337
13338free_mem:
13339 if( scanRequest.SSIDs.SSIDList )
13340 {
13341 vos_mem_free(scanRequest.SSIDs.SSIDList);
13342 }
13343
13344 if( channelList )
13345 vos_mem_free( channelList );
13346
13347 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013348 return status;
13349}
13350
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013351int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13352#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13353 struct net_device *dev,
13354#endif
13355 struct cfg80211_scan_request *request)
13356{
13357 int ret;
13358
13359 vos_ssr_protect(__func__);
13360 ret = __wlan_hdd_cfg80211_scan(wiphy,
13361#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13362 dev,
13363#endif
13364 request);
13365 vos_ssr_unprotect(__func__);
13366
13367 return ret;
13368}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013369
13370void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13371{
13372 v_U8_t iniDot11Mode =
13373 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13374 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13375
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013376 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13377 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013378 switch ( iniDot11Mode )
13379 {
13380 case eHDD_DOT11_MODE_AUTO:
13381 case eHDD_DOT11_MODE_11ac:
13382 case eHDD_DOT11_MODE_11ac_ONLY:
13383#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013384 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13385 sme_IsFeatureSupportedByFW(DOT11AC) )
13386 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13387 else
13388 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013389#else
13390 hddDot11Mode = eHDD_DOT11_MODE_11n;
13391#endif
13392 break;
13393 case eHDD_DOT11_MODE_11n:
13394 case eHDD_DOT11_MODE_11n_ONLY:
13395 hddDot11Mode = eHDD_DOT11_MODE_11n;
13396 break;
13397 default:
13398 hddDot11Mode = iniDot11Mode;
13399 break;
13400 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013401#ifdef WLAN_FEATURE_AP_HT40_24G
13402 if (operationChannel > SIR_11B_CHANNEL_END)
13403#endif
13404 {
13405 /* This call decides required channel bonding mode */
13406 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013407 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13408 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013409 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013410}
13411
Jeff Johnson295189b2012-06-20 16:38:30 -070013412/*
13413 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013414 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013415 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013416int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013417 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13418 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013419{
13420 int status = 0;
13421 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013422 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013423 v_U32_t roamId;
13424 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013425 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013426 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013427
13428 ENTER();
13429
13430 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013431 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13432
13433 status = wlan_hdd_validate_context(pHddCtx);
13434 if (status)
13435 {
Yue Mae36e3552014-03-05 17:06:20 -080013436 return status;
13437 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013438
Jeff Johnson295189b2012-06-20 16:38:30 -070013439 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13440 {
13441 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13442 return -EINVAL;
13443 }
13444
13445 pRoamProfile = &pWextState->roamProfile;
13446
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013447 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013448 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013449 hdd_station_ctx_t *pHddStaCtx;
13450 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013451
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013452 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13453
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013454 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013455 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13456 {
13457 /*QoS not enabled in cfg file*/
13458 pRoamProfile->uapsd_mask = 0;
13459 }
13460 else
13461 {
13462 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013463 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013464 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13465 }
13466
13467 pRoamProfile->SSIDs.numOfSSIDs = 1;
13468 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13469 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013470 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013471 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13472 ssid, ssid_len);
13473
13474 if (bssid)
13475 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013476 pValidBssid = bssid;
13477 }
13478 else if (bssid_hint)
13479 {
13480 pValidBssid = bssid_hint;
13481 }
13482 if (pValidBssid)
13483 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013484 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013485 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013486 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013487 /* Save BSSID in seperate variable as well, as RoamProfile
13488 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013489 case of join failure we should send valid BSSID to supplicant
13490 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013491 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013492 WNI_CFG_BSSID_LEN);
13493 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013494 else
13495 {
13496 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13497 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013498
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013499 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13500 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013501 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13502 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013503 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013504 /*set gen ie*/
13505 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13506 /*set auth*/
13507 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13508 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013509#ifdef FEATURE_WLAN_WAPI
13510 if (pAdapter->wapi_info.nWapiMode)
13511 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013512 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013513 switch (pAdapter->wapi_info.wapiAuthMode)
13514 {
13515 case WAPI_AUTH_MODE_PSK:
13516 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013517 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013518 pAdapter->wapi_info.wapiAuthMode);
13519 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13520 break;
13521 }
13522 case WAPI_AUTH_MODE_CERT:
13523 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013524 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013525 pAdapter->wapi_info.wapiAuthMode);
13526 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13527 break;
13528 }
13529 } // End of switch
13530 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13531 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13532 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013533 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013534 pRoamProfile->AuthType.numEntries = 1;
13535 pRoamProfile->EncryptionType.numEntries = 1;
13536 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13537 pRoamProfile->mcEncryptionType.numEntries = 1;
13538 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13539 }
13540 }
13541#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013542#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013543 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013544 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13545 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13546 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013547 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13548 sizeof (tSirGtkOffloadParams));
13549 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013550 }
13551#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013552 pRoamProfile->csrPersona = pAdapter->device_mode;
13553
Jeff Johnson32d95a32012-09-10 13:15:23 -070013554 if( operatingChannel )
13555 {
13556 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13557 pRoamProfile->ChannelInfo.numOfChannels = 1;
13558 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013559 else
13560 {
13561 pRoamProfile->ChannelInfo.ChannelList = NULL;
13562 pRoamProfile->ChannelInfo.numOfChannels = 0;
13563 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013564 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13565 {
13566 hdd_select_cbmode(pAdapter,operatingChannel);
13567 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013568
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013569 /*
13570 * Change conn_state to connecting before sme_RoamConnect(),
13571 * because sme_RoamConnect() has a direct path to call
13572 * hdd_smeRoamCallback(), which will change the conn_state
13573 * If direct path, conn_state will be accordingly changed
13574 * to NotConnected or Associated by either
13575 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13576 * in sme_RoamCallback()
13577 * if sme_RomConnect is to be queued,
13578 * Connecting state will remain until it is completed.
13579 * If connection state is not changed,
13580 * connection state will remain in eConnectionState_NotConnected state.
13581 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13582 * if conn state is eConnectionState_NotConnected.
13583 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13584 * informed of connect result indication which is an issue.
13585 */
13586
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013587 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13588 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013589 {
13590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013591 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013592 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13593 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013594 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013595 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013596 pAdapter->sessionId, pRoamProfile, &roamId);
13597
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013598 if ((eHAL_STATUS_SUCCESS != status) &&
13599 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13600 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013601
13602 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013603 hddLog(VOS_TRACE_LEVEL_ERROR,
13604 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13605 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013606 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013607 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013608 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013609 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013610
13611 pRoamProfile->ChannelInfo.ChannelList = NULL;
13612 pRoamProfile->ChannelInfo.numOfChannels = 0;
13613
Jeff Johnson295189b2012-06-20 16:38:30 -070013614 }
13615 else
13616 {
13617 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13618 return -EINVAL;
13619 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013620 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013621 return status;
13622}
13623
13624/*
13625 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
13626 * This function is used to set the authentication type (OPEN/SHARED).
13627 *
13628 */
13629static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
13630 enum nl80211_auth_type auth_type)
13631{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013632 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013633 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13634
13635 ENTER();
13636
13637 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013638 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070013639 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013640 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013641 hddLog(VOS_TRACE_LEVEL_INFO,
13642 "%s: set authentication type to AUTOSWITCH", __func__);
13643 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
13644 break;
13645
13646 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013647#ifdef WLAN_FEATURE_VOWIFI_11R
13648 case NL80211_AUTHTYPE_FT:
13649#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013650 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013651 "%s: set authentication type to OPEN", __func__);
13652 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
13653 break;
13654
13655 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013656 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013657 "%s: set authentication type to SHARED", __func__);
13658 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
13659 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013660#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013661 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013662 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013663 "%s: set authentication type to CCKM WPA", __func__);
13664 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
13665 break;
13666#endif
13667
13668
13669 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013670 hddLog(VOS_TRACE_LEVEL_ERROR,
13671 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013672 auth_type);
13673 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
13674 return -EINVAL;
13675 }
13676
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013677 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013678 pHddStaCtx->conn_info.authType;
13679 return 0;
13680}
13681
13682/*
13683 * FUNCTION: wlan_hdd_set_akm_suite
13684 * This function is used to set the key mgmt type(PSK/8021x).
13685 *
13686 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013687static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013688 u32 key_mgmt
13689 )
13690{
13691 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13692 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053013693 /* Should be in ieee802_11_defs.h */
13694#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
13695#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070013696 /*set key mgmt type*/
13697 switch(key_mgmt)
13698 {
13699 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053013700 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013701#ifdef WLAN_FEATURE_VOWIFI_11R
13702 case WLAN_AKM_SUITE_FT_PSK:
13703#endif
13704 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070013705 __func__);
13706 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
13707 break;
13708
13709 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053013710 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013711#ifdef WLAN_FEATURE_VOWIFI_11R
13712 case WLAN_AKM_SUITE_FT_8021X:
13713#endif
13714 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070013715 __func__);
13716 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13717 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013718#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013719#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
13720#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
13721 case WLAN_AKM_SUITE_CCKM:
13722 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
13723 __func__);
13724 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
13725 break;
13726#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070013727#ifndef WLAN_AKM_SUITE_OSEN
13728#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
13729 case WLAN_AKM_SUITE_OSEN:
13730 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
13731 __func__);
13732 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13733 break;
13734#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013735
13736 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013737 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013738 __func__, key_mgmt);
13739 return -EINVAL;
13740
13741 }
13742 return 0;
13743}
13744
13745/*
13746 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013747 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070013748 * (NONE/WEP40/WEP104/TKIP/CCMP).
13749 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013750static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
13751 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070013752 bool ucast
13753 )
13754{
13755 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013756 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013757 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13758
13759 ENTER();
13760
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013761 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013762 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013763 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070013764 __func__, cipher);
13765 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13766 }
13767 else
13768 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013769
Jeff Johnson295189b2012-06-20 16:38:30 -070013770 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013771 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013772 {
13773 case IW_AUTH_CIPHER_NONE:
13774 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13775 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013776
Jeff Johnson295189b2012-06-20 16:38:30 -070013777 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013778 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070013779 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013780
Jeff Johnson295189b2012-06-20 16:38:30 -070013781 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013782 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070013783 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013784
Jeff Johnson295189b2012-06-20 16:38:30 -070013785 case WLAN_CIPHER_SUITE_TKIP:
13786 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
13787 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013788
Jeff Johnson295189b2012-06-20 16:38:30 -070013789 case WLAN_CIPHER_SUITE_CCMP:
13790 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13791 break;
13792#ifdef FEATURE_WLAN_WAPI
13793 case WLAN_CIPHER_SUITE_SMS4:
13794 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
13795 break;
13796#endif
13797
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013798#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013799 case WLAN_CIPHER_SUITE_KRK:
13800 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
13801 break;
13802#endif
13803 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013804 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013805 __func__, cipher);
13806 return -EOPNOTSUPP;
13807 }
13808 }
13809
13810 if (ucast)
13811 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013812 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013813 __func__, encryptionType);
13814 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13815 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013816 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013817 encryptionType;
13818 }
13819 else
13820 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013821 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013822 __func__, encryptionType);
13823 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
13824 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
13825 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
13826 }
13827
13828 return 0;
13829}
13830
13831
13832/*
13833 * FUNCTION: wlan_hdd_cfg80211_set_ie
13834 * This function is used to parse WPA/RSN IE's.
13835 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013836int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013837#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13838 const u8 *ie,
13839#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013840 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013841#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013842 size_t ie_len
13843 )
13844{
13845 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013846#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13847 const u8 *genie = ie;
13848#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013849 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013850#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013851 v_U16_t remLen = ie_len;
13852#ifdef FEATURE_WLAN_WAPI
13853 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
13854 u16 *tmp;
13855 v_U16_t akmsuiteCount;
13856 int *akmlist;
13857#endif
13858 ENTER();
13859
13860 /* clear previous assocAddIE */
13861 pWextState->assocAddIE.length = 0;
13862 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013863 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013864
13865 while (remLen >= 2)
13866 {
13867 v_U16_t eLen = 0;
13868 v_U8_t elementId;
13869 elementId = *genie++;
13870 eLen = *genie++;
13871 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013872
Arif Hussain6d2a3322013-11-17 19:50:10 -080013873 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070013874 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013875
13876 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070013877 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013878 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013879 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 -070013880 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013881 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013882 "%s: Invalid WPA IE", __func__);
13883 return -EINVAL;
13884 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013885 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070013886 {
13887 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013888 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013889 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013890
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013891 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013892 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013893 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
13894 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013895 VOS_ASSERT(0);
13896 return -ENOMEM;
13897 }
13898 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13899 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13900 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013901
Jeff Johnson295189b2012-06-20 16:38:30 -070013902 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
13903 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13904 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13905 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013906 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
13907 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013908 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
13909 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
13910 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
13911 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
13912 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
13913 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013914 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053013915 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013916 {
13917 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013918 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013919 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013920
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013921 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013922 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013923 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13924 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013925 VOS_ASSERT(0);
13926 return -ENOMEM;
13927 }
13928 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13929 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13930 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013931
Jeff Johnson295189b2012-06-20 16:38:30 -070013932 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13933 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13934 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013935#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013936 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
13937 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013938 /*Consider WFD IE, only for P2P Client */
13939 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
13940 {
13941 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013942 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013943 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013944
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013945 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013946 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013947 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13948 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013949 VOS_ASSERT(0);
13950 return -ENOMEM;
13951 }
13952 // WFD IE is saved to Additional IE ; it should be accumulated to handle
13953 // WPS IE + P2P IE + WFD IE
13954 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13955 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013956
Jeff Johnson295189b2012-06-20 16:38:30 -070013957 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13958 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13959 }
13960#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013961 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013962 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013963 HS20_OUI_TYPE_SIZE)) )
13964 {
13965 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013966 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013967 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013968
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013969 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013970 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013971 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13972 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013973 VOS_ASSERT(0);
13974 return -ENOMEM;
13975 }
13976 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13977 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013978
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013979 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13980 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13981 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013982 /* Appending OSEN Information Element in Assiciation Request */
13983 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
13984 OSEN_OUI_TYPE_SIZE)) )
13985 {
13986 v_U16_t curAddIELen = pWextState->assocAddIE.length;
13987 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
13988 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013989
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013990 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013991 {
13992 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13993 "Need bigger buffer space");
13994 VOS_ASSERT(0);
13995 return -ENOMEM;
13996 }
13997 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13998 pWextState->assocAddIE.length += eLen + 2;
13999
14000 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
14001 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14002 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14003 }
14004
Abhishek Singh4322e622015-06-10 15:42:54 +053014005 /* Update only for WPA IE */
14006 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
14007 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014008
14009 /* populating as ADDIE in beacon frames */
14010 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014011 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014012 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
14013 {
14014 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14015 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
14016 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14017 {
14018 hddLog(LOGE,
14019 "Coldn't pass "
14020 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
14021 }
14022 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
14023 else
14024 hddLog(LOGE,
14025 "Could not pass on "
14026 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
14027
14028 /* IBSS mode doesn't contain params->proberesp_ies still
14029 beaconIE's need to be populated in probe response frames */
14030 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
14031 {
14032 u16 rem_probe_resp_ie_len = eLen + 2;
14033 u8 probe_rsp_ie_len[3] = {0};
14034 u8 counter = 0;
14035
14036 /* Check Probe Resp Length if it is greater then 255 then
14037 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
14038 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
14039 not able Store More then 255 bytes into One Variable */
14040
14041 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
14042 {
14043 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
14044 {
14045 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
14046 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
14047 }
14048 else
14049 {
14050 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
14051 rem_probe_resp_ie_len = 0;
14052 }
14053 }
14054
14055 rem_probe_resp_ie_len = 0;
14056
14057 if (probe_rsp_ie_len[0] > 0)
14058 {
14059 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14060 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
14061 (tANI_U8*)(genie - 2),
14062 probe_rsp_ie_len[0], NULL,
14063 eANI_BOOLEAN_FALSE)
14064 == eHAL_STATUS_FAILURE)
14065 {
14066 hddLog(LOGE,
14067 "Could not pass"
14068 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
14069 }
14070 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
14071 }
14072
14073 if (probe_rsp_ie_len[1] > 0)
14074 {
14075 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14076 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
14077 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14078 probe_rsp_ie_len[1], NULL,
14079 eANI_BOOLEAN_FALSE)
14080 == eHAL_STATUS_FAILURE)
14081 {
14082 hddLog(LOGE,
14083 "Could not pass"
14084 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14085 }
14086 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14087 }
14088
14089 if (probe_rsp_ie_len[2] > 0)
14090 {
14091 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14092 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14093 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14094 probe_rsp_ie_len[2], NULL,
14095 eANI_BOOLEAN_FALSE)
14096 == eHAL_STATUS_FAILURE)
14097 {
14098 hddLog(LOGE,
14099 "Could not pass"
14100 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14101 }
14102 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14103 }
14104
14105 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14106 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14107 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14108 {
14109 hddLog(LOGE,
14110 "Could not pass"
14111 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14112 }
14113 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014114 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014115 break;
14116 case DOT11F_EID_RSN:
14117 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14118 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14119 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14120 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14121 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14122 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014123
Abhishek Singhb16f3562016-01-20 11:08:32 +053014124 /* Appending extended capabilities with Interworking or
14125 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053014126 *
14127 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053014128 * interworkingService or bsstransition bit is set to 1.
14129 * Driver is only interested in interworkingService and
14130 * bsstransition capability from supplicant.
14131 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053014132 * required from supplicat, it needs to be handled while
14133 * sending Assoc Req in LIM.
14134 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014135 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014136 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014137 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014138 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014139 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014140
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014141 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014142 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014143 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14144 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014145 VOS_ASSERT(0);
14146 return -ENOMEM;
14147 }
14148 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14149 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014150
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014151 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14152 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14153 break;
14154 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014155#ifdef FEATURE_WLAN_WAPI
14156 case WLAN_EID_WAPI:
14157 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014158 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014159 pAdapter->wapi_info.nWapiMode);
14160 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014161 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014162 akmsuiteCount = WPA_GET_LE16(tmp);
14163 tmp = tmp + 1;
14164 akmlist = (int *)(tmp);
14165 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14166 {
14167 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14168 }
14169 else
14170 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014171 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014172 VOS_ASSERT(0);
14173 return -EINVAL;
14174 }
14175
14176 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14177 {
14178 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014179 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014180 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014181 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014182 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014183 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014184 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014185 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014186 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14187 }
14188 break;
14189#endif
14190 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014191 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014192 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014193 /* when Unknown IE is received we should break and continue
14194 * to the next IE in the buffer instead we were returning
14195 * so changing this to break */
14196 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014197 }
14198 genie += eLen;
14199 remLen -= eLen;
14200 }
14201 EXIT();
14202 return 0;
14203}
14204
14205/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014206 * FUNCTION: hdd_isWPAIEPresent
14207 * Parse the received IE to find the WPA IE
14208 *
14209 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014210static bool hdd_isWPAIEPresent(
14211#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14212 const u8 *ie,
14213#else
14214 u8 *ie,
14215#endif
14216 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014217{
14218 v_U8_t eLen = 0;
14219 v_U16_t remLen = ie_len;
14220 v_U8_t elementId = 0;
14221
14222 while (remLen >= 2)
14223 {
14224 elementId = *ie++;
14225 eLen = *ie++;
14226 remLen -= 2;
14227 if (eLen > remLen)
14228 {
14229 hddLog(VOS_TRACE_LEVEL_ERROR,
14230 "%s: IE length is wrong %d", __func__, eLen);
14231 return FALSE;
14232 }
14233 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14234 {
14235 /* OUI - 0x00 0X50 0XF2
14236 WPA Information Element - 0x01
14237 WPA version - 0x01*/
14238 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14239 return TRUE;
14240 }
14241 ie += eLen;
14242 remLen -= eLen;
14243 }
14244 return FALSE;
14245}
14246
14247/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014248 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014249 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014250 * parameters during connect operation.
14251 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014252int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014253 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014254 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014255{
14256 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014257 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014258 ENTER();
14259
14260 /*set wpa version*/
14261 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14262
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014263 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014264 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014265 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014266 {
14267 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14268 }
14269 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14270 {
14271 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14272 }
14273 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014274
14275 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014276 pWextState->wpaVersion);
14277
14278 /*set authentication type*/
14279 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14280
14281 if (0 > status)
14282 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014283 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014284 "%s: failed to set authentication type ", __func__);
14285 return status;
14286 }
14287
14288 /*set key mgmt type*/
14289 if (req->crypto.n_akm_suites)
14290 {
14291 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14292 if (0 > status)
14293 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014294 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014295 __func__);
14296 return status;
14297 }
14298 }
14299
14300 /*set pairwise cipher type*/
14301 if (req->crypto.n_ciphers_pairwise)
14302 {
14303 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14304 req->crypto.ciphers_pairwise[0], true);
14305 if (0 > status)
14306 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014307 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014308 "%s: failed to set unicast cipher type", __func__);
14309 return status;
14310 }
14311 }
14312 else
14313 {
14314 /*Reset previous cipher suite to none*/
14315 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14316 if (0 > status)
14317 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014318 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014319 "%s: failed to set unicast cipher type", __func__);
14320 return status;
14321 }
14322 }
14323
14324 /*set group cipher type*/
14325 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14326 false);
14327
14328 if (0 > status)
14329 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014330 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014331 __func__);
14332 return status;
14333 }
14334
Chet Lanctot186b5732013-03-18 10:26:30 -070014335#ifdef WLAN_FEATURE_11W
14336 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14337#endif
14338
Jeff Johnson295189b2012-06-20 16:38:30 -070014339 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14340 if (req->ie_len)
14341 {
14342 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14343 if ( 0 > status)
14344 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014345 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014346 __func__);
14347 return status;
14348 }
14349 }
14350
14351 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014352 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014353 {
14354 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14355 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14356 )
14357 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014358 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014359 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14360 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014361 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014362 __func__);
14363 return -EOPNOTSUPP;
14364 }
14365 else
14366 {
14367 u8 key_len = req->key_len;
14368 u8 key_idx = req->key_idx;
14369
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014370 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014371 && (CSR_MAX_NUM_KEY > key_idx)
14372 )
14373 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014374 hddLog(VOS_TRACE_LEVEL_INFO,
14375 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014376 __func__, key_idx, key_len);
14377 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014378 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014379 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014380 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014381 (u8)key_len;
14382 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14383 }
14384 }
14385 }
14386 }
14387
14388 return status;
14389}
14390
14391/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014392 * FUNCTION: wlan_hdd_try_disconnect
14393 * This function is used to disconnect from previous
14394 * connection
14395 */
14396static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14397{
14398 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014399 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014400 hdd_station_ctx_t *pHddStaCtx;
14401 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014402 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014403
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014404 ret = wlan_hdd_validate_context(pHddCtx);
14405 if (0 != ret)
14406 {
14407 return ret;
14408 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014409 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14410
14411 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14412
14413 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14414 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053014415 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014416 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14417 {
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014418 spin_lock_bh(&pAdapter->lock_for_active_session);
14419 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14420 {
14421 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14422 }
14423 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053014424 hdd_connSetConnectionState(pHddStaCtx,
14425 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014426 /* Issue disconnect to CSR */
14427 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014428 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014429 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014430 eCSR_DISCONNECT_REASON_UNSPECIFIED);
14431 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
14432 hddLog(LOG1,
14433 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
14434 } else if ( 0 != status ) {
14435 hddLog(LOGE,
14436 FL("csrRoamDisconnect failure, returned %d"),
14437 (int)status );
14438 result = -EINVAL;
14439 goto disconnected;
14440 }
14441 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014442 &pAdapter->disconnect_comp_var,
14443 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014444 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
14445 hddLog(LOGE,
14446 "%s: Failed to disconnect, timed out", __func__);
14447 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014448 }
14449 }
14450 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14451 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014452 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014453 &pAdapter->disconnect_comp_var,
14454 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014455 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014456 {
14457 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014458 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014459 }
14460 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014461disconnected:
14462 hddLog(LOG1,
14463 FL("Set HDD connState to eConnectionState_NotConnected"));
14464 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14465 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014466}
14467
14468/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014469 * FUNCTION: __wlan_hdd_cfg80211_connect
14470 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014471 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014472static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014473 struct net_device *ndev,
14474 struct cfg80211_connect_params *req
14475 )
14476{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014477 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014478 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053014479#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
14480 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014481 const u8 *bssid_hint = req->bssid_hint;
14482#else
14483 const u8 *bssid_hint = NULL;
14484#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014485 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014486 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014487 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014488
14489 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014490
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014491 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14492 TRACE_CODE_HDD_CFG80211_CONNECT,
14493 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014494 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014495 "%s: device_mode = %s (%d)", __func__,
14496 hdd_device_modetoString(pAdapter->device_mode),
14497 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014498
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014499 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014500 if (!pHddCtx)
14501 {
14502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14503 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014504 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014505 }
14506
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014507 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014508 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014509 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014510 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014511 }
14512
Agarwal Ashish51325b52014-06-16 16:50:49 +053014513
Jeff Johnson295189b2012-06-20 16:38:30 -070014514#ifdef WLAN_BTAMP_FEATURE
14515 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014516 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014517 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014518 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014519 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014520 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014521 }
14522#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014523
14524 //If Device Mode is Station Concurrent Sessions Exit BMps
14525 //P2P Mode will be taken care in Open/close adapter
14526 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014527 (vos_concurrent_open_sessions_running())) {
14528 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14529 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014530 }
14531
14532 /*Try disconnecting if already in connected state*/
14533 status = wlan_hdd_try_disconnect(pAdapter);
14534 if ( 0 > status)
14535 {
14536 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14537 " connection"));
14538 return -EALREADY;
14539 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053014540 /* Check for max concurrent connections after doing disconnect if any*/
14541 if (vos_max_concurrent_connections_reached()) {
14542 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14543 return -ECONNREFUSED;
14544 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014545
Jeff Johnson295189b2012-06-20 16:38:30 -070014546 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014547 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014548
14549 if ( 0 > status)
14550 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014551 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014552 __func__);
14553 return status;
14554 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053014555
14556 if (pHddCtx->spoofMacAddr.isEnabled)
14557 {
14558 hddLog(VOS_TRACE_LEVEL_INFO,
14559 "%s: MAC Spoofing enabled ", __func__);
14560 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14561 * to fill TxBds for probe request during SSID scan which may happen
14562 * as part of connect command
14563 */
14564 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
14565 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
14566 if (status != VOS_STATUS_SUCCESS)
14567 return -ECONNREFUSED;
14568 }
14569
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014570 if (req->channel)
14571 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070014572 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014573 channel = 0;
14574 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14575 req->ssid_len, req->bssid,
14576 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014577
Sushant Kaushikd7083982015-03-18 14:33:24 +053014578 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014579 {
14580 //ReEnable BMPS if disabled
14581 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
14582 (NULL != pHddCtx))
14583 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053014584 if (pHddCtx->hdd_wlan_suspended)
14585 {
14586 hdd_set_pwrparams(pHddCtx);
14587 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014588 //ReEnable Bmps and Imps back
14589 hdd_enable_bmps_imps(pHddCtx);
14590 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014591 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070014592 return status;
14593 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014594 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014595 EXIT();
14596 return status;
14597}
14598
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014599static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
14600 struct net_device *ndev,
14601 struct cfg80211_connect_params *req)
14602{
14603 int ret;
14604 vos_ssr_protect(__func__);
14605 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
14606 vos_ssr_unprotect(__func__);
14607
14608 return ret;
14609}
Jeff Johnson295189b2012-06-20 16:38:30 -070014610
14611/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014612 * FUNCTION: wlan_hdd_disconnect
14613 * This function is used to issue a disconnect request to SME
14614 */
14615int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
14616{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014617 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014618 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014619 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014620 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014621
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014622 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014623
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014624 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014625 if (0 != status)
14626 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014627 return status;
14628 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053014629 /* Indicate sme of disconnect so that in progress connection or preauth
14630 * can be aborted
14631 */
14632 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053014633 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014634 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014635
Agarwal Ashish47d18112014-08-04 19:55:07 +053014636 /* Need to apply spin lock before decreasing active sessions
14637 * as there can be chance for double decrement if context switch
14638 * Calls hdd_DisConnectHandler.
14639 */
14640
14641 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014642 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14643 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014644 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14645 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053014646 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
14647 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014648
Abhishek Singhf4669da2014-05-26 15:07:49 +053014649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053014650 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
14651
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014652 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014653
Mihir Shete182a0b22014-08-18 16:08:48 +053014654 /*
14655 * stop tx queues before deleting STA/BSS context from the firmware.
14656 * tx has to be disabled because the firmware can get busy dropping
14657 * the tx frames after BSS/STA has been deleted and will not send
14658 * back a response resulting in WDI timeout
14659 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053014660 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053014661 netif_tx_disable(pAdapter->dev);
14662 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014663
Mihir Shete182a0b22014-08-18 16:08:48 +053014664 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014665 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14666 pAdapter->sessionId, reason);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014667 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
14668 {
14669 hddLog(LOG1,
14670 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014671 }
14672 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014673 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014674 hddLog(LOGE,
14675 FL("csrRoamDisconnect failure, returned %d"),
14676 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014677 result = -EINVAL;
14678 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014679 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014680 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014681 &pAdapter->disconnect_comp_var,
14682 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014683 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014684 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014685 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014686 "%s: Failed to disconnect, timed out", __func__);
Ratnam Rachuri38027182016-03-15 16:05:59 +053014687 VOS_BUG(0);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014688 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014689 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014690disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014691 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014692 FL("Set HDD connState to eConnectionState_NotConnected"));
14693 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14694
Abhishek Singh087de602015-10-21 17:18:55 +053014695#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
14696 /* Sending disconnect event to userspace for kernel version < 3.11
14697 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
14698 */
14699 hddLog(LOG1, FL("Send disconnected event to userspace"));
14700 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
14701 NULL, 0, GFP_KERNEL);
14702#endif
14703
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014704 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014705 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014706}
14707
14708
14709/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014710 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070014711 * This function is used to issue a disconnect request to SME
14712 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014713static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014714 struct net_device *dev,
14715 u16 reason
14716 )
14717{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014718 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014719 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014720 tCsrRoamProfile *pRoamProfile;
14721 hdd_station_ctx_t *pHddStaCtx;
14722 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014723#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014724 tANI_U8 staIdx;
14725#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014726
Jeff Johnson295189b2012-06-20 16:38:30 -070014727 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014728
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014729 if (!pAdapter) {
14730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14731 return -EINVAL;
14732 }
14733
14734 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14735 if (!pHddStaCtx) {
14736 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
14737 return -EINVAL;
14738 }
14739
14740 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14741 status = wlan_hdd_validate_context(pHddCtx);
14742 if (0 != status)
14743 {
14744 return status;
14745 }
14746
14747 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
14748
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014749 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14750 TRACE_CODE_HDD_CFG80211_DISCONNECT,
14751 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014752 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
14753 __func__, hdd_device_modetoString(pAdapter->device_mode),
14754 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014755
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014756 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
14757 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070014758
Jeff Johnson295189b2012-06-20 16:38:30 -070014759 if (NULL != pRoamProfile)
14760 {
14761 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014762 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
14763 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070014764 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014765 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070014766 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014767 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014768 switch(reason)
14769 {
14770 case WLAN_REASON_MIC_FAILURE:
14771 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
14772 break;
14773
14774 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
14775 case WLAN_REASON_DISASSOC_AP_BUSY:
14776 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
14777 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
14778 break;
14779
14780 case WLAN_REASON_PREV_AUTH_NOT_VALID:
14781 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053014782 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070014783 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
14784 break;
14785
Jeff Johnson295189b2012-06-20 16:38:30 -070014786 default:
14787 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
14788 break;
14789 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014790 pScanInfo = &pHddCtx->scan_info;
14791 if (pScanInfo->mScanPending)
14792 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014793 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014794 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014795 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014796 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014797 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053014798 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014799#ifdef FEATURE_WLAN_TDLS
14800 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014801 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014802 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014803 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
14804 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014805 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014806 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014807 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014809 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014810 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014811 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014812 status = sme_DeleteTdlsPeerSta(
14813 WLAN_HDD_GET_HAL_CTX(pAdapter),
14814 pAdapter->sessionId,
14815 mac);
14816 if (status != eHAL_STATUS_SUCCESS) {
14817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
14818 return -EPERM;
14819 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014820 }
14821 }
14822#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014823 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014824 status = wlan_hdd_disconnect(pAdapter, reasonCode);
14825 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070014826 {
14827 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014828 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014829 __func__, (int)status );
14830 return -EINVAL;
14831 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014832 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014833 else
14834 {
14835 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
14836 "called while in %d state", __func__,
14837 pHddStaCtx->conn_info.connState);
14838 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014839 }
14840 else
14841 {
14842 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
14843 }
14844
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014845 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014846 return status;
14847}
14848
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014849static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
14850 struct net_device *dev,
14851 u16 reason
14852 )
14853{
14854 int ret;
14855 vos_ssr_protect(__func__);
14856 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
14857 vos_ssr_unprotect(__func__);
14858
14859 return ret;
14860}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014861
Jeff Johnson295189b2012-06-20 16:38:30 -070014862/*
14863 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014864 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014865 * settings in IBSS mode.
14866 */
14867static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014868 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014869 struct cfg80211_ibss_params *params
14870 )
14871{
14872 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014873 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014874 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14875 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014876
Jeff Johnson295189b2012-06-20 16:38:30 -070014877 ENTER();
14878
14879 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070014880 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070014881
14882 if (params->ie_len && ( NULL != params->ie) )
14883 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014884 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14885 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014886 {
14887 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14888 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14889 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014890 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014891 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014892 tDot11fIEWPA dot11WPAIE;
14893 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014894 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014895
Wilson Yang00256342013-10-10 23:13:38 -070014896 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014897 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14898 params->ie_len, DOT11F_EID_WPA);
14899 if ( NULL != ie )
14900 {
14901 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14902 // Unpack the WPA IE
14903 //Skip past the EID byte and length byte - and four byte WiFi OUI
14904 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
14905 &ie[2+4],
14906 ie[1] - 4,
14907 &dot11WPAIE);
14908 /*Extract the multicast cipher, the encType for unicast
14909 cipher for wpa-none is none*/
14910 encryptionType =
14911 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
14912 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014913 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014914
Jeff Johnson295189b2012-06-20 16:38:30 -070014915 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
14916
14917 if (0 > status)
14918 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014919 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014920 __func__);
14921 return status;
14922 }
14923 }
14924
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014925 pWextState->roamProfile.AuthType.authType[0] =
14926 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014927 eCSR_AUTH_TYPE_OPEN_SYSTEM;
14928
14929 if (params->privacy)
14930 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014931 /* Security enabled IBSS, At this time there is no information available
14932 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070014933 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014934 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070014935 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014936 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070014937 *enable privacy bit in beacons */
14938
14939 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
14940 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014941 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
14942 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070014943 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14944 pWextState->roamProfile.EncryptionType.numEntries = 1;
14945 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070014946 return status;
14947}
14948
14949/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014950 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014951 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070014952 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014953static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014954 struct net_device *dev,
14955 struct cfg80211_ibss_params *params
14956 )
14957{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014958 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014959 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14960 tCsrRoamProfile *pRoamProfile;
14961 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014962 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14963 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014964 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070014965
14966 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014967
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014968 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14969 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
14970 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014971 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014972 "%s: device_mode = %s (%d)", __func__,
14973 hdd_device_modetoString(pAdapter->device_mode),
14974 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014975
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014976 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014977 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014978 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014979 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014980 }
14981
14982 if (NULL == pWextState)
14983 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014984 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070014985 __func__);
14986 return -EIO;
14987 }
14988
Agarwal Ashish51325b52014-06-16 16:50:49 +053014989 if (vos_max_concurrent_connections_reached()) {
14990 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14991 return -ECONNREFUSED;
14992 }
14993
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014994 /*Try disconnecting if already in connected state*/
14995 status = wlan_hdd_try_disconnect(pAdapter);
14996 if ( 0 > status)
14997 {
14998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14999 " IBSS connection"));
15000 return -EALREADY;
15001 }
15002
Jeff Johnson295189b2012-06-20 16:38:30 -070015003 pRoamProfile = &pWextState->roamProfile;
15004
15005 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
15006 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015007 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015008 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015009 return -EINVAL;
15010 }
15011
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015012 /* BSSID is provided by upper layers hence no need to AUTO generate */
15013 if (NULL != params->bssid) {
15014 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15015 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
15016 hddLog (VOS_TRACE_LEVEL_ERROR,
15017 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15018 return -EIO;
15019 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015020 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015021 }
krunal sonie9002db2013-11-25 14:24:17 -080015022 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
15023 {
15024 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15025 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
15026 {
15027 hddLog (VOS_TRACE_LEVEL_ERROR,
15028 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15029 return -EIO;
15030 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015031
15032 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080015033 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015034 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080015035 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015036
Jeff Johnson295189b2012-06-20 16:38:30 -070015037 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070015038 if (NULL !=
15039#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15040 params->chandef.chan)
15041#else
15042 params->channel)
15043#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015044 {
15045 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015046 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15047 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
15048 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15049 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015050
15051 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015052 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070015053 ieee80211_frequency_to_channel(
15054#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15055 params->chandef.chan->center_freq);
15056#else
15057 params->channel->center_freq);
15058#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015059
15060 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15061 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070015062 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015063 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
15064 __func__);
15065 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070015066 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015067
15068 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015069 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015070 if (channelNum == validChan[indx])
15071 {
15072 break;
15073 }
15074 }
15075 if (indx >= numChans)
15076 {
15077 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015078 __func__, channelNum);
15079 return -EINVAL;
15080 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015081 /* Set the Operational Channel */
15082 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
15083 channelNum);
15084 pRoamProfile->ChannelInfo.numOfChannels = 1;
15085 pHddStaCtx->conn_info.operationChannel = channelNum;
15086 pRoamProfile->ChannelInfo.ChannelList =
15087 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070015088 }
15089
15090 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015091 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070015092 if (status < 0)
15093 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015094 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070015095 __func__);
15096 return status;
15097 }
15098
15099 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015100 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053015101 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015102 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015103
15104 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015105 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015106
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015107 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015108 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015109}
15110
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015111static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
15112 struct net_device *dev,
15113 struct cfg80211_ibss_params *params
15114 )
15115{
15116 int ret = 0;
15117
15118 vos_ssr_protect(__func__);
15119 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15120 vos_ssr_unprotect(__func__);
15121
15122 return ret;
15123}
15124
Jeff Johnson295189b2012-06-20 16:38:30 -070015125/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015126 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015127 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015128 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015129static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015130 struct net_device *dev
15131 )
15132{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015133 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015134 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15135 tCsrRoamProfile *pRoamProfile;
15136 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015137 int status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015138#ifdef WLAN_FEATURE_RMC
15139 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
15140#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015141
15142 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015143
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015144 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15145 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15146 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015147 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015148 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015149 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015150 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015151 }
15152
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015153 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15154 hdd_device_modetoString(pAdapter->device_mode),
15155 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015156 if (NULL == pWextState)
15157 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015158 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015159 __func__);
15160 return -EIO;
15161 }
15162
15163 pRoamProfile = &pWextState->roamProfile;
15164
15165 /* Issue disconnect only if interface type is set to IBSS */
15166 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15167 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015168 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015169 __func__);
15170 return -EINVAL;
15171 }
15172
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015173#ifdef WLAN_FEATURE_RMC
15174 /* Clearing add IE of beacon */
15175 if (ccmCfgSetStr(pHddCtx->hHal,
15176 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
15177 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
15178 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15179 {
15180 hddLog (VOS_TRACE_LEVEL_ERROR,
15181 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
15182 return -EINVAL;
15183 }
15184 if (ccmCfgSetInt(pHddCtx->hHal,
15185 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
15186 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15187 {
15188 hddLog (VOS_TRACE_LEVEL_ERROR,
15189 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
15190 __func__);
15191 return -EINVAL;
15192 }
15193
15194 // Reset WNI_CFG_PROBE_RSP Flags
15195 wlan_hdd_reset_prob_rspies(pAdapter);
15196
15197 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15198 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
15199 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15200 {
15201 hddLog (VOS_TRACE_LEVEL_ERROR,
15202 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
15203 __func__);
15204 return -EINVAL;
15205 }
15206#endif
15207
Jeff Johnson295189b2012-06-20 16:38:30 -070015208 /* Issue Disconnect request */
15209 INIT_COMPLETION(pAdapter->disconnect_comp_var);
15210 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15211 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15212
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015213 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015214 return 0;
15215}
15216
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015217static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15218 struct net_device *dev
15219 )
15220{
15221 int ret = 0;
15222
15223 vos_ssr_protect(__func__);
15224 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15225 vos_ssr_unprotect(__func__);
15226
15227 return ret;
15228}
15229
Jeff Johnson295189b2012-06-20 16:38:30 -070015230/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015231 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015232 * This function is used to set the phy parameters
15233 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15234 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015235static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015236 u32 changed)
15237{
15238 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15239 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015240 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015241
15242 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015243
15244 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015245 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15246 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015247
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015248 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015249 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015250 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015251 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015252 }
15253
Jeff Johnson295189b2012-06-20 16:38:30 -070015254 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15255 {
15256 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15257 WNI_CFG_RTS_THRESHOLD_STAMAX :
15258 wiphy->rts_threshold;
15259
15260 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015261 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015262 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015263 hddLog(VOS_TRACE_LEVEL_ERROR,
15264 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015265 __func__, rts_threshold);
15266 return -EINVAL;
15267 }
15268
15269 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15270 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015271 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015272 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015273 hddLog(VOS_TRACE_LEVEL_ERROR,
15274 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015275 __func__, rts_threshold);
15276 return -EIO;
15277 }
15278
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015279 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015280 rts_threshold);
15281 }
15282
15283 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15284 {
15285 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15286 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15287 wiphy->frag_threshold;
15288
15289 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015290 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015291 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015292 hddLog(VOS_TRACE_LEVEL_ERROR,
15293 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015294 frag_threshold);
15295 return -EINVAL;
15296 }
15297
15298 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15299 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015300 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015301 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015302 hddLog(VOS_TRACE_LEVEL_ERROR,
15303 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015304 __func__, frag_threshold);
15305 return -EIO;
15306 }
15307
15308 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15309 frag_threshold);
15310 }
15311
15312 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15313 || (changed & WIPHY_PARAM_RETRY_LONG))
15314 {
15315 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15316 wiphy->retry_short :
15317 wiphy->retry_long;
15318
15319 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15320 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15321 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015322 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015323 __func__, retry_value);
15324 return -EINVAL;
15325 }
15326
15327 if (changed & WIPHY_PARAM_RETRY_SHORT)
15328 {
15329 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15330 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015331 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015332 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015333 hddLog(VOS_TRACE_LEVEL_ERROR,
15334 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015335 __func__, retry_value);
15336 return -EIO;
15337 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015338 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015339 __func__, retry_value);
15340 }
15341 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15342 {
15343 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15344 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015345 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015346 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015347 hddLog(VOS_TRACE_LEVEL_ERROR,
15348 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015349 __func__, retry_value);
15350 return -EIO;
15351 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015352 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015353 __func__, retry_value);
15354 }
15355 }
15356
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015357 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015358 return 0;
15359}
15360
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015361static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15362 u32 changed)
15363{
15364 int ret;
15365
15366 vos_ssr_protect(__func__);
15367 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15368 vos_ssr_unprotect(__func__);
15369
15370 return ret;
15371}
15372
Jeff Johnson295189b2012-06-20 16:38:30 -070015373/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015374 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015375 * This function is used to set the txpower
15376 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015377static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015378#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15379 struct wireless_dev *wdev,
15380#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015381#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015382 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015383#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015384 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015385#endif
15386 int dbm)
15387{
15388 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015389 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015390 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15391 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015392 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015393
15394 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015395
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015396 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15397 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15398 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015399 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015400 if (0 != status)
15401 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015402 return status;
15403 }
15404
15405 hHal = pHddCtx->hHal;
15406
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015407 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15408 dbm, ccmCfgSetCallback,
15409 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015410 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015411 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015412 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15413 return -EIO;
15414 }
15415
15416 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15417 dbm);
15418
15419 switch(type)
15420 {
15421 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15422 /* Fall through */
15423 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15424 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15425 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015426 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15427 __func__);
15428 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015429 }
15430 break;
15431 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015432 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015433 __func__);
15434 return -EOPNOTSUPP;
15435 break;
15436 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015437 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15438 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015439 return -EIO;
15440 }
15441
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015442 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015443 return 0;
15444}
15445
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015446static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15447#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15448 struct wireless_dev *wdev,
15449#endif
15450#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15451 enum tx_power_setting type,
15452#else
15453 enum nl80211_tx_power_setting type,
15454#endif
15455 int dbm)
15456{
15457 int ret;
15458 vos_ssr_protect(__func__);
15459 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15460#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15461 wdev,
15462#endif
15463#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15464 type,
15465#else
15466 type,
15467#endif
15468 dbm);
15469 vos_ssr_unprotect(__func__);
15470
15471 return ret;
15472}
15473
Jeff Johnson295189b2012-06-20 16:38:30 -070015474/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015475 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015476 * This function is used to read the txpower
15477 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015478static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015479#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15480 struct wireless_dev *wdev,
15481#endif
15482 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015483{
15484
15485 hdd_adapter_t *pAdapter;
15486 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015487 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015488
Jeff Johnsone7245742012-09-05 17:12:55 -070015489 ENTER();
15490
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015491 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015492 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015493 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015494 *dbm = 0;
15495 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015496 }
15497
Jeff Johnson295189b2012-06-20 16:38:30 -070015498 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15499 if (NULL == pAdapter)
15500 {
15501 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15502 return -ENOENT;
15503 }
15504
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015505 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15506 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15507 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015508 wlan_hdd_get_classAstats(pAdapter);
15509 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15510
Jeff Johnsone7245742012-09-05 17:12:55 -070015511 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015512 return 0;
15513}
15514
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015515static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15516#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15517 struct wireless_dev *wdev,
15518#endif
15519 int *dbm)
15520{
15521 int ret;
15522
15523 vos_ssr_protect(__func__);
15524 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15525#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15526 wdev,
15527#endif
15528 dbm);
15529 vos_ssr_unprotect(__func__);
15530
15531 return ret;
15532}
15533
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015534static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015535#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15536 const u8* mac,
15537#else
15538 u8* mac,
15539#endif
15540 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015541{
15542 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15543 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15544 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053015545 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015546
15547 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
15548 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070015549
15550 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
15551 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
15552 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
15553 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
15554 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
15555 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
15556 tANI_U16 maxRate = 0;
15557 tANI_U16 myRate;
15558 tANI_U16 currentRate = 0;
15559 tANI_U8 maxSpeedMCS = 0;
15560 tANI_U8 maxMCSIdx = 0;
15561 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053015562 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070015563 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015564 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015565
Leo Chang6f8870f2013-03-26 18:11:36 -070015566#ifdef WLAN_FEATURE_11AC
15567 tANI_U32 vht_mcs_map;
15568 eDataRate11ACMaxMcs vhtMaxMcs;
15569#endif /* WLAN_FEATURE_11AC */
15570
Jeff Johnsone7245742012-09-05 17:12:55 -070015571 ENTER();
15572
Jeff Johnson295189b2012-06-20 16:38:30 -070015573 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15574 (0 == ssidlen))
15575 {
15576 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
15577 " Invalid ssidlen, %d", __func__, ssidlen);
15578 /*To keep GUI happy*/
15579 return 0;
15580 }
15581
Mukul Sharma811205f2014-07-09 21:07:30 +053015582 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
15583 {
15584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15585 "%s: Roaming in progress, so unable to proceed this request", __func__);
15586 return 0;
15587 }
15588
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015589 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015590 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015591 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015592 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015593 }
15594
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053015595 wlan_hdd_get_station_stats(pAdapter);
15596 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015597
Kiet Lam3b17fc82013-09-27 05:24:08 +053015598 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
15599 sinfo->filled |= STATION_INFO_SIGNAL;
15600
c_hpothu09f19542014-05-30 21:53:31 +053015601 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053015602 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
15603 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053015604 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053015605 {
15606 rate_flags = pAdapter->maxRateFlags;
15607 }
c_hpothu44ff4e02014-05-08 00:13:57 +053015608
Jeff Johnson295189b2012-06-20 16:38:30 -070015609 //convert to the UI units of 100kbps
15610 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
15611
15612#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070015613 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 -070015614 sinfo->signal,
15615 pCfg->reportMaxLinkSpeed,
15616 myRate,
15617 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015618 (int) pCfg->linkSpeedRssiMid,
15619 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070015620 (int) rate_flags,
15621 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070015622#endif //LINKSPEED_DEBUG_ENABLED
15623
15624 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
15625 {
15626 // we do not want to necessarily report the current speed
15627 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
15628 {
15629 // report the max possible speed
15630 rssidx = 0;
15631 }
15632 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
15633 {
15634 // report the max possible speed with RSSI scaling
15635 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
15636 {
15637 // report the max possible speed
15638 rssidx = 0;
15639 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015640 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070015641 {
15642 // report middle speed
15643 rssidx = 1;
15644 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015645 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
15646 {
15647 // report middle speed
15648 rssidx = 2;
15649 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015650 else
15651 {
15652 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015653 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070015654 }
15655 }
15656 else
15657 {
15658 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
15659 hddLog(VOS_TRACE_LEVEL_ERROR,
15660 "%s: Invalid value for reportMaxLinkSpeed: %u",
15661 __func__, pCfg->reportMaxLinkSpeed);
15662 rssidx = 0;
15663 }
15664
15665 maxRate = 0;
15666
15667 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015668 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
15669 OperationalRates, &ORLeng))
15670 {
15671 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15672 /*To keep GUI happy*/
15673 return 0;
15674 }
15675
Jeff Johnson295189b2012-06-20 16:38:30 -070015676 for (i = 0; i < ORLeng; i++)
15677 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015678 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015679 {
15680 /* Validate Rate Set */
15681 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
15682 {
15683 currentRate = supported_data_rate[j].supported_rate[rssidx];
15684 break;
15685 }
15686 }
15687 /* Update MAX rate */
15688 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15689 }
15690
15691 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015692 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
15693 ExtendedRates, &ERLeng))
15694 {
15695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15696 /*To keep GUI happy*/
15697 return 0;
15698 }
15699
Jeff Johnson295189b2012-06-20 16:38:30 -070015700 for (i = 0; i < ERLeng; i++)
15701 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015702 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015703 {
15704 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
15705 {
15706 currentRate = supported_data_rate[j].supported_rate[rssidx];
15707 break;
15708 }
15709 }
15710 /* Update MAX rate */
15711 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15712 }
c_hpothu79aab322014-07-14 21:11:01 +053015713
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015714 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053015715 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015716 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053015717 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070015718 {
c_hpothu79aab322014-07-14 21:11:01 +053015719 if (rate_flags & eHAL_TX_RATE_VHT80)
15720 mode = 2;
15721 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
15722 mode = 1;
15723 else
15724 mode = 0;
15725
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015726 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
15727 MCSRates, &MCSLeng))
15728 {
15729 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15730 /*To keep GUI happy*/
15731 return 0;
15732 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015733 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070015734#ifdef WLAN_FEATURE_11AC
15735 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015736 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070015737 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015738 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015739 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070015740 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070015741 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015742 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015743 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015744 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070015745 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015746 maxMCSIdx = 7;
15747 }
15748 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
15749 {
15750 maxMCSIdx = 8;
15751 }
15752 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
15753 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015754 //VHT20 is supporting 0~8
15755 if (rate_flags & eHAL_TX_RATE_VHT20)
15756 maxMCSIdx = 8;
15757 else
15758 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070015759 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015760
c_hpothu79aab322014-07-14 21:11:01 +053015761 if (0 != rssidx)/*check for scaled */
15762 {
15763 //get middle rate MCS index if rssi=1/2
15764 for (i=0; i <= maxMCSIdx; i++)
15765 {
15766 if (sinfo->signal <= rssiMcsTbl[mode][i])
15767 {
15768 maxMCSIdx = i;
15769 break;
15770 }
15771 }
15772 }
15773
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015774 if (rate_flags & eHAL_TX_RATE_VHT80)
15775 {
15776 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
15777 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
15778 }
15779 else if (rate_flags & eHAL_TX_RATE_VHT40)
15780 {
15781 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
15782 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
15783 }
15784 else if (rate_flags & eHAL_TX_RATE_VHT20)
15785 {
15786 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
15787 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
15788 }
15789
Leo Chang6f8870f2013-03-26 18:11:36 -070015790 maxSpeedMCS = 1;
15791 if (currentRate > maxRate)
15792 {
15793 maxRate = currentRate;
15794 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015795
Leo Chang6f8870f2013-03-26 18:11:36 -070015796 }
15797 else
15798#endif /* WLAN_FEATURE_11AC */
15799 {
15800 if (rate_flags & eHAL_TX_RATE_HT40)
15801 {
15802 rateFlag |= 1;
15803 }
15804 if (rate_flags & eHAL_TX_RATE_SGI)
15805 {
15806 rateFlag |= 2;
15807 }
15808
Girish Gowli01abcee2014-07-31 20:18:55 +053015809 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053015810 if (rssidx == 1 || rssidx == 2)
15811 {
15812 //get middle rate MCS index if rssi=1/2
15813 for (i=0; i <= 7; i++)
15814 {
15815 if (sinfo->signal <= rssiMcsTbl[mode][i])
15816 {
15817 temp = i+1;
15818 break;
15819 }
15820 }
15821 }
c_hpothu79aab322014-07-14 21:11:01 +053015822
15823 for (i = 0; i < MCSLeng; i++)
15824 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015825 for (j = 0; j < temp; j++)
15826 {
15827 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
15828 {
15829 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015830 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015831 break;
15832 }
15833 }
15834 if ((j < temp) && (currentRate > maxRate))
15835 {
15836 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070015837 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015838 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015839 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015840 }
15841 }
15842
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015843 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
15844 {
15845 maxRate = myRate;
15846 maxSpeedMCS = 1;
15847 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15848 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015849 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053015850 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070015851 {
15852 maxRate = myRate;
15853 if (rate_flags & eHAL_TX_RATE_LEGACY)
15854 {
15855 maxSpeedMCS = 0;
15856 }
15857 else
15858 {
15859 maxSpeedMCS = 1;
15860 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15861 }
15862 }
15863
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015864 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070015865 {
15866 sinfo->txrate.legacy = maxRate;
15867#ifdef LINKSPEED_DEBUG_ENABLED
15868 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
15869#endif //LINKSPEED_DEBUG_ENABLED
15870 }
15871 else
15872 {
15873 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070015874#ifdef WLAN_FEATURE_11AC
15875 sinfo->txrate.nss = 1;
15876 if (rate_flags & eHAL_TX_RATE_VHT80)
15877 {
15878 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015879 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070015880 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015881 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070015882 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015883 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15884 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15885 }
15886 else if (rate_flags & eHAL_TX_RATE_VHT20)
15887 {
15888 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15889 }
15890#endif /* WLAN_FEATURE_11AC */
15891 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
15892 {
15893 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15894 if (rate_flags & eHAL_TX_RATE_HT40)
15895 {
15896 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15897 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015898 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015899 if (rate_flags & eHAL_TX_RATE_SGI)
15900 {
15901 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15902 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015903
Jeff Johnson295189b2012-06-20 16:38:30 -070015904#ifdef LINKSPEED_DEBUG_ENABLED
15905 pr_info("Reporting MCS rate %d flags %x\n",
15906 sinfo->txrate.mcs,
15907 sinfo->txrate.flags );
15908#endif //LINKSPEED_DEBUG_ENABLED
15909 }
15910 }
15911 else
15912 {
15913 // report current rate instead of max rate
15914
15915 if (rate_flags & eHAL_TX_RATE_LEGACY)
15916 {
15917 //provide to the UI in units of 100kbps
15918 sinfo->txrate.legacy = myRate;
15919#ifdef LINKSPEED_DEBUG_ENABLED
15920 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
15921#endif //LINKSPEED_DEBUG_ENABLED
15922 }
15923 else
15924 {
15925 //must be MCS
15926 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015927#ifdef WLAN_FEATURE_11AC
15928 sinfo->txrate.nss = 1;
15929 if (rate_flags & eHAL_TX_RATE_VHT80)
15930 {
15931 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15932 }
15933 else
15934#endif /* WLAN_FEATURE_11AC */
15935 {
15936 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15937 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015938 if (rate_flags & eHAL_TX_RATE_SGI)
15939 {
15940 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15941 }
15942 if (rate_flags & eHAL_TX_RATE_HT40)
15943 {
15944 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15945 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015946#ifdef WLAN_FEATURE_11AC
15947 else if (rate_flags & eHAL_TX_RATE_VHT80)
15948 {
15949 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
15950 }
15951#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070015952#ifdef LINKSPEED_DEBUG_ENABLED
15953 pr_info("Reporting actual MCS rate %d flags %x\n",
15954 sinfo->txrate.mcs,
15955 sinfo->txrate.flags );
15956#endif //LINKSPEED_DEBUG_ENABLED
15957 }
15958 }
15959 sinfo->filled |= STATION_INFO_TX_BITRATE;
15960
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070015961 sinfo->tx_packets =
15962 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
15963 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
15964 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
15965 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
15966
15967 sinfo->tx_retries =
15968 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
15969 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
15970 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
15971 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
15972
15973 sinfo->tx_failed =
15974 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
15975 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
15976 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
15977 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
15978
15979 sinfo->filled |=
15980 STATION_INFO_TX_PACKETS |
15981 STATION_INFO_TX_RETRIES |
15982 STATION_INFO_TX_FAILED;
15983
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053015984 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
15985 sinfo->filled |= STATION_INFO_RX_PACKETS;
15986
15987 if (rate_flags & eHAL_TX_RATE_LEGACY)
15988 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
15989 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
15990 sinfo->rx_packets);
15991 else
15992 hddLog(LOG1,
15993 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
15994 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
15995 sinfo->tx_packets, sinfo->rx_packets);
15996
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015997 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15998 TRACE_CODE_HDD_CFG80211_GET_STA,
15999 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016000 EXIT();
16001 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016002}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016003#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16004static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16005 const u8* mac, struct station_info *sinfo)
16006#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016007static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16008 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016009#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016010{
16011 int ret;
16012
16013 vos_ssr_protect(__func__);
16014 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
16015 vos_ssr_unprotect(__func__);
16016
16017 return ret;
16018}
16019
16020static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070016021 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070016022{
16023 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016024 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016025 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016026 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016027
Jeff Johnsone7245742012-09-05 17:12:55 -070016028 ENTER();
16029
Jeff Johnson295189b2012-06-20 16:38:30 -070016030 if (NULL == pAdapter)
16031 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016032 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016033 return -ENODEV;
16034 }
16035
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016036 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16037 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
16038 pAdapter->sessionId, timeout));
16039
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016040 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016041 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016042 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016043 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016044 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016045 }
16046
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016047 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
16048 (TRUE == pHddCtx->hdd_wlan_suspended) &&
16049 (pHddCtx->cfg_ini->fhostArpOffload) &&
16050 (eConnectionState_Associated ==
16051 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
16052 {
Amar Singhald53568e2013-09-26 11:03:45 -070016053
16054 hddLog(VOS_TRACE_LEVEL_INFO,
16055 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053016056 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016057 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16058 {
16059 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016060 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016061 __func__, vos_status);
16062 }
16063 }
16064
Jeff Johnson295189b2012-06-20 16:38:30 -070016065 /**The get power cmd from the supplicant gets updated by the nl only
16066 *on successful execution of the function call
16067 *we are oppositely mapped w.r.t mode in the driver
16068 **/
16069 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
16070
16071 if (VOS_STATUS_E_FAILURE == vos_status)
16072 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16074 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016075 return -EINVAL;
16076 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016077 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016078 return 0;
16079}
16080
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016081static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
16082 struct net_device *dev, bool mode, int timeout)
16083{
16084 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016085
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016086 vos_ssr_protect(__func__);
16087 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
16088 vos_ssr_unprotect(__func__);
16089
16090 return ret;
16091}
Sushant Kaushik084f6592015-09-10 13:11:56 +053016092
Jeff Johnson295189b2012-06-20 16:38:30 -070016093#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016094static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
16095 struct net_device *netdev,
16096 u8 key_index)
16097{
16098 ENTER();
16099 return 0;
16100}
16101
Jeff Johnson295189b2012-06-20 16:38:30 -070016102static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016103 struct net_device *netdev,
16104 u8 key_index)
16105{
16106 int ret;
16107 vos_ssr_protect(__func__);
16108 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
16109 vos_ssr_unprotect(__func__);
16110 return ret;
16111}
16112#endif //LINUX_VERSION_CODE
16113
16114#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16115static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16116 struct net_device *dev,
16117 struct ieee80211_txq_params *params)
16118{
16119 ENTER();
16120 return 0;
16121}
16122#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16123static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16124 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016125{
Jeff Johnsone7245742012-09-05 17:12:55 -070016126 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070016127 return 0;
16128}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016129#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070016130
16131#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16132static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016133 struct net_device *dev,
16134 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016135{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016136 int ret;
16137
16138 vos_ssr_protect(__func__);
16139 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
16140 vos_ssr_unprotect(__func__);
16141 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016142}
16143#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16144static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
16145 struct ieee80211_txq_params *params)
16146{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016147 int ret;
16148
16149 vos_ssr_protect(__func__);
16150 ret = __wlan_hdd_set_txq_params(wiphy, params);
16151 vos_ssr_unprotect(__func__);
16152 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016153}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016154#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016155
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016156static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016157 struct net_device *dev,
16158 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070016159{
16160 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016161 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016162 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016163 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016164 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016165 v_CONTEXT_t pVosContext = NULL;
16166 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016167
Jeff Johnsone7245742012-09-05 17:12:55 -070016168 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016169
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016170 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016171 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016172 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016173 return -EINVAL;
16174 }
16175
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016176 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16177 TRACE_CODE_HDD_CFG80211_DEL_STA,
16178 pAdapter->sessionId, pAdapter->device_mode));
16179
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016180 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16181 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016182 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016183 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016184 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016185 }
16186
Jeff Johnson295189b2012-06-20 16:38:30 -070016187 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016188 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016189 )
16190 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016191 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16192 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16193 if(pSapCtx == NULL){
16194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16195 FL("psapCtx is NULL"));
16196 return -ENOENT;
16197 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016198 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016199 {
16200 v_U16_t i;
16201 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16202 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016203 if ((pSapCtx->aStaInfo[i].isUsed) &&
16204 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016205 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016206 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016207 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016208 ETHER_ADDR_LEN);
16209
Jeff Johnson295189b2012-06-20 16:38:30 -070016210 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016211 "%s: Delete STA with MAC::"
16212 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016213 __func__,
16214 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16215 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016216 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016217 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016218 }
16219 }
16220 }
16221 else
16222 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016223
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016224 vos_status = hdd_softap_GetStaId(pAdapter,
16225 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016226 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16227 {
16228 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016229 "%s: Skip this DEL STA as this is not used::"
16230 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016231 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016232 return -ENOENT;
16233 }
16234
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016235 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016236 {
16237 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016238 "%s: Skip this DEL STA as deauth is in progress::"
16239 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016240 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016241 return -ENOENT;
16242 }
16243
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016244 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016245
Jeff Johnson295189b2012-06-20 16:38:30 -070016246 hddLog(VOS_TRACE_LEVEL_INFO,
16247 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016248 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016249 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016250 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016251
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016252 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016253 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16254 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016255 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016256 hddLog(VOS_TRACE_LEVEL_INFO,
16257 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016258 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016259 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016260 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016261 return -ENOENT;
16262 }
16263
Jeff Johnson295189b2012-06-20 16:38:30 -070016264 }
16265 }
16266
16267 EXIT();
16268
16269 return 0;
16270}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016271
16272#ifdef CFG80211_DEL_STA_V2
16273static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16274 struct net_device *dev,
16275 struct station_del_parameters *param)
16276#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016277#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16278static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16279 struct net_device *dev, const u8 *mac)
16280#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016281static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16282 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016283#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016284#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016285{
16286 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016287 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016288
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016289 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016290
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016291#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016292 if (NULL == param) {
16293 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016294 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016295 return -EINVAL;
16296 }
16297
16298 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16299 param->subtype, &delStaParams);
16300
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016301#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016302 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016303 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016304#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016305 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16306
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016307 vos_ssr_unprotect(__func__);
16308
16309 return ret;
16310}
16311
16312static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016313 struct net_device *dev,
16314#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16315 const u8 *mac,
16316#else
16317 u8 *mac,
16318#endif
16319 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016320{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016321 hdd_adapter_t *pAdapter;
16322 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016323 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016324#ifdef FEATURE_WLAN_TDLS
16325 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016326
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016327 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016328
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016329 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16330 if (NULL == pAdapter)
16331 {
16332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16333 "%s: Adapter is NULL",__func__);
16334 return -EINVAL;
16335 }
16336 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16337 status = wlan_hdd_validate_context(pHddCtx);
16338 if (0 != status)
16339 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016340 return status;
16341 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016342
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016343 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16344 TRACE_CODE_HDD_CFG80211_ADD_STA,
16345 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016346 mask = params->sta_flags_mask;
16347
16348 set = params->sta_flags_set;
16349
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016351 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16352 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016353
16354 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16355 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016356 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016357 }
16358 }
16359#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016360 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016361 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016362}
16363
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016364#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16365static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16366 struct net_device *dev, const u8 *mac,
16367 struct station_parameters *params)
16368#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016369static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16370 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016371#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016372{
16373 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016374
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016375 vos_ssr_protect(__func__);
16376 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16377 vos_ssr_unprotect(__func__);
16378
16379 return ret;
16380}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016381#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016382
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016383static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016384 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016385{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016386 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16387 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016388 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016389 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016390 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016391 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016392
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016393 ENTER();
16394
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016395 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016396 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016397 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016398 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016399 return -EINVAL;
16400 }
16401
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016402 if (!pmksa) {
16403 hddLog(LOGE, FL("pmksa is NULL"));
16404 return -EINVAL;
16405 }
16406
16407 if (!pmksa->bssid || !pmksa->pmkid) {
16408 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16409 pmksa->bssid, pmksa->pmkid);
16410 return -EINVAL;
16411 }
16412
16413 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16414 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16415
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016416 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16417 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016418 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016419 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016420 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016421 }
16422
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016423 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016424 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16425
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016426 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16427 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016428
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016429 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016430 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016431 &pmk_id, 1, FALSE);
16432
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016433 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16434 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16435 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016436
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016437 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016438 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016439}
16440
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016441static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16442 struct cfg80211_pmksa *pmksa)
16443{
16444 int ret;
16445
16446 vos_ssr_protect(__func__);
16447 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16448 vos_ssr_unprotect(__func__);
16449
16450 return ret;
16451}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016452
Wilson Yang6507c4e2013-10-01 20:11:19 -070016453
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016454static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016455 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016456{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016457 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16458 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016459 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016460 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016461
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016462 ENTER();
16463
Wilson Yang6507c4e2013-10-01 20:11:19 -070016464 /* Validate pAdapter */
16465 if (NULL == pAdapter)
16466 {
16467 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16468 return -EINVAL;
16469 }
16470
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016471 if (!pmksa) {
16472 hddLog(LOGE, FL("pmksa is NULL"));
16473 return -EINVAL;
16474 }
16475
16476 if (!pmksa->bssid) {
16477 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16478 return -EINVAL;
16479 }
16480
Kiet Lam98c46a12014-10-31 15:34:57 -070016481 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16482 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16483
Wilson Yang6507c4e2013-10-01 20:11:19 -070016484 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16485 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016486 if (0 != status)
16487 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016488 return status;
16489 }
16490
16491 /*Retrieve halHandle*/
16492 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16493
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016494 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16495 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16496 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016497 /* Delete the PMKID CSR cache */
16498 if (eHAL_STATUS_SUCCESS !=
16499 sme_RoamDelPMKIDfromCache(halHandle,
16500 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16501 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16502 MAC_ADDR_ARRAY(pmksa->bssid));
16503 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016504 }
16505
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016506 EXIT();
16507 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016508}
16509
Wilson Yang6507c4e2013-10-01 20:11:19 -070016510
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016511static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16512 struct cfg80211_pmksa *pmksa)
16513{
16514 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016515
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016516 vos_ssr_protect(__func__);
16517 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16518 vos_ssr_unprotect(__func__);
16519
16520 return ret;
16521
16522}
16523
16524static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016525{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016526 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16527 tHalHandle halHandle;
16528 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016529 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016530
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016531 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016532
16533 /* Validate pAdapter */
16534 if (NULL == pAdapter)
16535 {
16536 hddLog(VOS_TRACE_LEVEL_ERROR,
16537 "%s: Invalid Adapter" ,__func__);
16538 return -EINVAL;
16539 }
16540
16541 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16542 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016543 if (0 != status)
16544 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016545 return status;
16546 }
16547
16548 /*Retrieve halHandle*/
16549 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16550
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016551 /* Flush the PMKID cache in CSR */
16552 if (eHAL_STATUS_SUCCESS !=
16553 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
16554 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
16555 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016556 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016557 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080016558 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016559}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016560
16561static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
16562{
16563 int ret;
16564
16565 vos_ssr_protect(__func__);
16566 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
16567 vos_ssr_unprotect(__func__);
16568
16569 return ret;
16570}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016571#endif
16572
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016573#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016574static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16575 struct net_device *dev,
16576 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016577{
16578 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16579 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016580 hdd_context_t *pHddCtx;
16581 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016582
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016583 ENTER();
16584
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016585 if (NULL == pAdapter)
16586 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016587 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016588 return -ENODEV;
16589 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016590 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16591 ret = wlan_hdd_validate_context(pHddCtx);
16592 if (0 != ret)
16593 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016594 return ret;
16595 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016596 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016597 if (NULL == pHddStaCtx)
16598 {
16599 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
16600 return -EINVAL;
16601 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016602
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016603 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16604 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
16605 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016606 // Added for debug on reception of Re-assoc Req.
16607 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
16608 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016609 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016610 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080016611 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016612 }
16613
16614#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080016615 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016616 ftie->ie_len);
16617#endif
16618
16619 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016620 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
16621 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016622 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016623
16624 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016625 return 0;
16626}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016627
16628static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16629 struct net_device *dev,
16630 struct cfg80211_update_ft_ies_params *ftie)
16631{
16632 int ret;
16633
16634 vos_ssr_protect(__func__);
16635 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
16636 vos_ssr_unprotect(__func__);
16637
16638 return ret;
16639}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016640#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016641
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016642#ifdef FEATURE_WLAN_SCAN_PNO
16643
16644void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
16645 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
16646{
16647 int ret;
16648 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
16649 hdd_context_t *pHddCtx;
16650
Nirav Shah80830bf2013-12-31 16:35:12 +053016651 ENTER();
16652
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016653 if (NULL == pAdapter)
16654 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016656 "%s: HDD adapter is Null", __func__);
16657 return ;
16658 }
16659
16660 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16661 if (NULL == pHddCtx)
16662 {
16663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16664 "%s: HDD context is Null!!!", __func__);
16665 return ;
16666 }
16667
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016668 spin_lock(&pHddCtx->schedScan_lock);
16669 if (TRUE == pHddCtx->isWiphySuspended)
16670 {
16671 pHddCtx->isSchedScanUpdatePending = TRUE;
16672 spin_unlock(&pHddCtx->schedScan_lock);
16673 hddLog(VOS_TRACE_LEVEL_INFO,
16674 "%s: Update cfg80211 scan database after it resume", __func__);
16675 return ;
16676 }
16677 spin_unlock(&pHddCtx->schedScan_lock);
16678
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016679 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
16680
16681 if (0 > ret)
16682 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053016683 else
16684 {
16685 /* Acquire wakelock to handle the case where APP's tries to suspend
16686 * immediatly after the driver gets connect request(i.e after pno)
16687 * from supplicant, this result in app's is suspending and not able
16688 * to process the connect request to AP */
16689 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
16690 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016691 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16693 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016694}
16695
16696/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016697 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016698 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016699 */
16700static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
16701{
16702 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16703 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016704 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016705 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16706 int status = 0;
16707 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
16708
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016709 /* The current firmware design does not allow PNO during any
16710 * active sessions. Hence, determine the active sessions
16711 * and return a failure.
16712 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016713 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
16714 {
16715 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016716 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016717
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016718 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
16719 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
16720 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
16721 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
16722 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053016723 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016724 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016725 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016726 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016727 }
16728 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16729 pAdapterNode = pNext;
16730 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016731 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016732}
16733
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016734void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
16735{
16736 hdd_adapter_t *pAdapter = callbackContext;
16737 hdd_context_t *pHddCtx;
16738
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016739 ENTER();
16740
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016741 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
16742 {
16743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16744 FL("Invalid adapter or adapter has invalid magic"));
16745 return;
16746 }
16747
16748 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16749 if (0 != wlan_hdd_validate_context(pHddCtx))
16750 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016751 return;
16752 }
16753
c_hpothub53c45d2014-08-18 16:53:14 +053016754 if (VOS_STATUS_SUCCESS != status)
16755 {
16756 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016757 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053016758 pHddCtx->isPnoEnable = FALSE;
16759 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016760
16761 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
16762 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016763 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016764}
16765
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016766/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016767 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
16768 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016769 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016770static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016771 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16772{
16773 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016774 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016775 hdd_context_t *pHddCtx;
16776 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016777 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053016778 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
16779 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016780 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16781 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016782 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016783 hdd_config_t *pConfig = NULL;
16784 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016785
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016786 ENTER();
16787
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016788 if (NULL == pAdapter)
16789 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016791 "%s: HDD adapter is Null", __func__);
16792 return -ENODEV;
16793 }
16794
16795 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016796 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016797
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016798 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016799 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016800 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016801 }
16802
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016803 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016804 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16805 if (NULL == hHal)
16806 {
16807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16808 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016809 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016810 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016811 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16812 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
16813 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053016814 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016815 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053016816 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016817 {
16818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16819 "%s: aborting the existing scan is unsuccessfull", __func__);
16820 return -EBUSY;
16821 }
16822
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016823 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016824 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016826 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016827 return -EBUSY;
16828 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016829
c_hpothu37f21312014-04-09 21:49:54 +053016830 if (TRUE == pHddCtx->isPnoEnable)
16831 {
16832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16833 FL("already PNO is enabled"));
16834 return -EBUSY;
16835 }
c_hpothu225aa7c2014-10-22 17:45:13 +053016836
16837 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
16838 {
16839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16840 "%s: abort ROC failed ", __func__);
16841 return -EBUSY;
16842 }
16843
c_hpothu37f21312014-04-09 21:49:54 +053016844 pHddCtx->isPnoEnable = TRUE;
16845
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016846 pnoRequest.enable = 1; /*Enable PNO */
16847 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016848
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016849 if (( !pnoRequest.ucNetworksCount ) ||
16850 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016851 {
16852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016853 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016854 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016855 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016856 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016857 goto error;
16858 }
16859
16860 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
16861 {
16862 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016863 "%s: Incorrect number of channels %d",
16864 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016865 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016866 goto error;
16867 }
16868
16869 /* Framework provides one set of channels(all)
16870 * common for all saved profile */
16871 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16872 channels_allowed, &num_channels_allowed))
16873 {
16874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16875 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016876 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016877 goto error;
16878 }
16879 /* Checking each channel against allowed channel list */
16880 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053016881 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016882 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016883 char chList [(request->n_channels*5)+1];
16884 int len;
16885 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016886 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016887 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016888 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016889 if (request->channels[i]->hw_value == channels_allowed[indx])
16890 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016891 if ((!pConfig->enableDFSPnoChnlScan) &&
16892 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
16893 {
16894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16895 "%s : Dropping DFS channel : %d",
16896 __func__,channels_allowed[indx]);
16897 num_ignore_dfs_ch++;
16898 break;
16899 }
16900
Nirav Shah80830bf2013-12-31 16:35:12 +053016901 valid_ch[num_ch++] = request->channels[i]->hw_value;
16902 len += snprintf(chList+len, 5, "%d ",
16903 request->channels[i]->hw_value);
16904 break ;
16905 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016906 }
16907 }
Nirav Shah80830bf2013-12-31 16:35:12 +053016908 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016909
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016910 /*If all channels are DFS and dropped, then ignore the PNO request*/
16911 if (num_ignore_dfs_ch == request->n_channels)
16912 {
16913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16914 "%s : All requested channels are DFS channels", __func__);
16915 ret = -EINVAL;
16916 goto error;
16917 }
16918 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016919
16920 pnoRequest.aNetworks =
16921 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16922 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016923 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016924 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16925 FL("failed to allocate memory aNetworks %u"),
16926 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16927 goto error;
16928 }
16929 vos_mem_zero(pnoRequest.aNetworks,
16930 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16931
16932 /* Filling per profile params */
16933 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
16934 {
16935 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016936 request->match_sets[i].ssid.ssid_len;
16937
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016938 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
16939 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016940 {
16941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016942 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016943 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016944 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016945 goto error;
16946 }
16947
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016948 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016949 request->match_sets[i].ssid.ssid,
16950 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16952 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016953 i, pnoRequest.aNetworks[i].ssId.ssId);
16954 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
16955 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
16956 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016957
16958 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016959 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
16960 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016961
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016962 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016963 }
16964
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016965 for (i = 0; i < request->n_ssids; i++)
16966 {
16967 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016968 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016969 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016970 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016971 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016972 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016973 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016974 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016975 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016976 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016977 break;
16978 }
16979 j++;
16980 }
16981 }
16982 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16983 "Number of hidden networks being Configured = %d",
16984 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080016986 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016987
16988 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
16989 if (pnoRequest.p24GProbeTemplate == NULL)
16990 {
16991 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16992 FL("failed to allocate memory p24GProbeTemplate %u"),
16993 SIR_PNO_MAX_PB_REQ_SIZE);
16994 goto error;
16995 }
16996
16997 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
16998 if (pnoRequest.p5GProbeTemplate == NULL)
16999 {
17000 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17001 FL("failed to allocate memory p5GProbeTemplate %u"),
17002 SIR_PNO_MAX_PB_REQ_SIZE);
17003 goto error;
17004 }
17005
17006 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17007 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17008
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053017009 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
17010 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017011 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017012 pnoRequest.us24GProbeTemplateLen = request->ie_len;
17013 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
17014 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017015
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017016 pnoRequest.us5GProbeTemplateLen = request->ie_len;
17017 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
17018 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017019 }
17020
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017021 /* Driver gets only one time interval which is hardcoded in
17022 * supplicant for 10000ms. Taking power consumption into account 6 timers
17023 * will be used, Timervalue is increased exponentially i.e 10,20,40,
17024 * 80,160,320 secs. And number of scan cycle for each timer
17025 * is configurable through INI param gPNOScanTimerRepeatValue.
17026 * If it is set to 0 only one timer will be used and PNO scan cycle
17027 * will be repeated after each interval specified by supplicant
17028 * till PNO is disabled.
17029 */
17030 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017031 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017032 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017033 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017034 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
17035
17036 tempInterval = (request->interval)/1000;
17037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17038 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
17039 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017040 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017041 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017042 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017043 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017044 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017045 tempInterval *= 2;
17046 }
17047 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017048 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017049
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017050 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017051
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017052 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017053 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17054 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017055 pAdapter->pno_req_status = 0;
17056
Nirav Shah80830bf2013-12-31 16:35:12 +053017057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17058 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017059 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
17060 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053017061
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017062 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017063 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017064 hdd_cfg80211_sched_scan_done_callback, pAdapter);
17065 if (eHAL_STATUS_SUCCESS != status)
17066 {
17067 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017068 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017069 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017070 goto error;
17071 }
17072
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017073 ret = wait_for_completion_timeout(
17074 &pAdapter->pno_comp_var,
17075 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17076 if (0 >= ret)
17077 {
17078 // Did not receive the response for PNO enable in time.
17079 // Assuming the PNO enable was success.
17080 // Returning error from here, because we timeout, results
17081 // in side effect of Wifi (Wifi Setting) not to work.
17082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17083 FL("Timed out waiting for PNO to be Enabled"));
17084 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017085 }
17086
17087 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053017088 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017089
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017090error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17092 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053017093 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017094 if (pnoRequest.aNetworks)
17095 vos_mem_free(pnoRequest.aNetworks);
17096 if (pnoRequest.p24GProbeTemplate)
17097 vos_mem_free(pnoRequest.p24GProbeTemplate);
17098 if (pnoRequest.p5GProbeTemplate)
17099 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017100
17101 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017102 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017103}
17104
17105/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017106 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
17107 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017108 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017109static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
17110 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17111{
17112 int ret;
17113
17114 vos_ssr_protect(__func__);
17115 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
17116 vos_ssr_unprotect(__func__);
17117
17118 return ret;
17119}
17120
17121/*
17122 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
17123 * Function to disable PNO
17124 */
17125static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017126 struct net_device *dev)
17127{
17128 eHalStatus status = eHAL_STATUS_FAILURE;
17129 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17130 hdd_context_t *pHddCtx;
17131 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017132 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017133 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017134
17135 ENTER();
17136
17137 if (NULL == pAdapter)
17138 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017140 "%s: HDD adapter is Null", __func__);
17141 return -ENODEV;
17142 }
17143
17144 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017145
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017146 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017147 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017148 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017149 "%s: HDD context is Null", __func__);
17150 return -ENODEV;
17151 }
17152
17153 /* The return 0 is intentional when isLogpInProgress and
17154 * isLoadUnloadInProgress. We did observe a crash due to a return of
17155 * failure in sched_scan_stop , especially for a case where the unload
17156 * of the happens at the same time. The function __cfg80211_stop_sched_scan
17157 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
17158 * success. If it returns a failure , then its next invocation due to the
17159 * clean up of the second interface will have the dev pointer corresponding
17160 * to the first one leading to a crash.
17161 */
17162 if (pHddCtx->isLogpInProgress)
17163 {
17164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17165 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017166 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017167 return ret;
17168 }
17169
Mihir Shete18156292014-03-11 15:38:30 +053017170 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017171 {
17172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17173 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17174 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017175 }
17176
17177 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17178 if (NULL == hHal)
17179 {
17180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17181 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017182 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017183 }
17184
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017185 pnoRequest.enable = 0; /* Disable PNO */
17186 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017187
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017188 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17189 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17190 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017191
17192 INIT_COMPLETION(pAdapter->pno_comp_var);
17193 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17194 pnoRequest.callbackContext = pAdapter;
17195 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017196 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017197 pAdapter->sessionId,
17198 NULL, pAdapter);
17199 if (eHAL_STATUS_SUCCESS != status)
17200 {
17201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17202 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017203 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017204 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017205 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017206 ret = wait_for_completion_timeout(
17207 &pAdapter->pno_comp_var,
17208 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17209 if (0 >= ret)
17210 {
17211 // Did not receive the response for PNO disable in time.
17212 // Assuming the PNO disable was success.
17213 // Returning error from here, because we timeout, results
17214 // in side effect of Wifi (Wifi Setting) not to work.
17215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17216 FL("Timed out waiting for PNO to be disabled"));
17217 ret = 0;
17218 }
17219
17220 ret = pAdapter->pno_req_status;
17221 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017222
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017223error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017225 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017226
17227 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017228 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017229}
17230
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017231/*
17232 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17233 * NL interface to disable PNO
17234 */
17235static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17236 struct net_device *dev)
17237{
17238 int ret;
17239
17240 vos_ssr_protect(__func__);
17241 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17242 vos_ssr_unprotect(__func__);
17243
17244 return ret;
17245}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017246#endif /*FEATURE_WLAN_SCAN_PNO*/
17247
17248
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017249#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017250#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017251static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17252 struct net_device *dev,
17253 u8 *peer, u8 action_code,
17254 u8 dialog_token,
17255 u16 status_code, u32 peer_capability,
17256 const u8 *buf, size_t len)
17257#else /* TDLS_MGMT_VERSION2 */
17258#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17259static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17260 struct net_device *dev,
17261 const u8 *peer, u8 action_code,
17262 u8 dialog_token, u16 status_code,
17263 u32 peer_capability, bool initiator,
17264 const u8 *buf, size_t len)
17265#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17266static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17267 struct net_device *dev,
17268 const u8 *peer, u8 action_code,
17269 u8 dialog_token, u16 status_code,
17270 u32 peer_capability, const u8 *buf,
17271 size_t len)
17272#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17273static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17274 struct net_device *dev,
17275 u8 *peer, u8 action_code,
17276 u8 dialog_token,
17277 u16 status_code, u32 peer_capability,
17278 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017279#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017280static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17281 struct net_device *dev,
17282 u8 *peer, u8 action_code,
17283 u8 dialog_token,
17284 u16 status_code, const u8 *buf,
17285 size_t len)
17286#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017287#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017288{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017289 hdd_adapter_t *pAdapter;
17290 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017291 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017292 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017293 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017294 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017295 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017296 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017297#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017298 u32 peer_capability = 0;
17299#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017300 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017301 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017302
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017303 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17304 if (NULL == pAdapter)
17305 {
17306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17307 "%s: Adapter is NULL",__func__);
17308 return -EINVAL;
17309 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017310 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17311 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17312 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017313
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017314 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017315 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017316 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017318 "Invalid arguments");
17319 return -EINVAL;
17320 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017321
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017322 if (pHddCtx->isLogpInProgress)
17323 {
17324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17325 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017326 wlan_hdd_tdls_set_link_status(pAdapter,
17327 peer,
17328 eTDLS_LINK_IDLE,
17329 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017330 return -EBUSY;
17331 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017332
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017333 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17334 {
17335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17336 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17337 return -EAGAIN;
17338 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017339
Hoonki Lee27511902013-03-14 18:19:06 -070017340 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017341 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017343 "%s: TDLS mode is disabled OR not enabled in FW."
17344 MAC_ADDRESS_STR " action %d declined.",
17345 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017346 return -ENOTSUPP;
17347 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017348
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017349 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17350
17351 if( NULL == pHddStaCtx )
17352 {
17353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17354 "%s: HDD station context NULL ",__func__);
17355 return -EINVAL;
17356 }
17357
17358 /* STA should be connected and authenticated
17359 * before sending any TDLS frames
17360 */
17361 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17362 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17363 {
17364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17365 "STA is not connected or unauthenticated. "
17366 "connState %u, uIsAuthenticated %u",
17367 pHddStaCtx->conn_info.connState,
17368 pHddStaCtx->conn_info.uIsAuthenticated);
17369 return -EAGAIN;
17370 }
17371
Hoonki Lee27511902013-03-14 18:19:06 -070017372 /* other than teardown frame, other mgmt frames are not sent if disabled */
17373 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17374 {
17375 /* if tdls_mode is disabled to respond to peer's request */
17376 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17377 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017379 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017380 " TDLS mode is disabled. action %d declined.",
17381 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017382
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017383 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017384 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017385
17386 if (vos_max_concurrent_connections_reached())
17387 {
17388 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17389 return -EINVAL;
17390 }
Hoonki Lee27511902013-03-14 18:19:06 -070017391 }
17392
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017393 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17394 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017395 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017396 {
17397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017398 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017399 " TDLS setup is ongoing. action %d declined.",
17400 __func__, MAC_ADDR_ARRAY(peer), action_code);
17401 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017402 }
17403 }
17404
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017405 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17406 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017407 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017408 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17409 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017410 {
17411 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17412 we return error code at 'add_station()'. Hence we have this
17413 check again in addtion to add_station().
17414 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017415 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017416 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17418 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017419 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
17420 __func__, MAC_ADDR_ARRAY(peer), action_code,
17421 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053017422 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080017423 }
17424 else
17425 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017426 /* maximum reached. tweak to send error code to peer and return
17427 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017428 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17430 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017431 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
17432 __func__, MAC_ADDR_ARRAY(peer), status_code,
17433 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070017434 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017435 /* fall through to send setup resp with failure status
17436 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017437 }
17438 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017439 else
17440 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017441 mutex_lock(&pHddCtx->tdls_lock);
17442 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017443 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017444 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017445 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017447 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17448 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017449 return -EPERM;
17450 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017451 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017452 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017453 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017454
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017456 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017457 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17458 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017459
Hoonki Leea34dd892013-02-05 22:56:02 -080017460 /*Except teardown responder will not be used so just make 0*/
17461 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017462 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017463 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017464
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017465 mutex_lock(&pHddCtx->tdls_lock);
17466 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017467
17468 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17469 responder = pTdlsPeer->is_responder;
17470 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017471 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017473 "%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 -070017474 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17475 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017476 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017477 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017478 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017479 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017480 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017481
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017482 /* Discard TDLS setup if peer is removed by user app */
17483 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
17484 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17485 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
17486 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
17487
17488 mutex_lock(&pHddCtx->tdls_lock);
17489 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17490 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
17491 mutex_unlock(&pHddCtx->tdls_lock);
17492 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
17493 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
17494 MAC_ADDR_ARRAY(peer), action_code);
17495 return -EINVAL;
17496 }
17497 mutex_unlock(&pHddCtx->tdls_lock);
17498 }
17499
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017500 /* For explicit trigger of DIS_REQ come out of BMPS for
17501 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017502 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053017503 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017504 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17505 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070017506 {
17507 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
17508 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017510 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017511 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
17512 if (status != VOS_STATUS_SUCCESS) {
17513 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
17514 }
Hoonki Lee14621352013-04-16 17:51:19 -070017515 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017516 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017517 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017518 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
17519 }
17520 }
Hoonki Lee14621352013-04-16 17:51:19 -070017521 }
17522
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017523 /* make sure doesn't call send_mgmt() while it is pending */
17524 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
17525 {
17526 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017527 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017528 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017529 ret = -EBUSY;
17530 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017531 }
17532
17533 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017534 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
17535
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017536 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
17537 pAdapter->sessionId, peer, action_code, dialog_token,
17538 status_code, peer_capability, (tANI_U8 *)buf, len,
17539 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017540
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017541 if (VOS_STATUS_SUCCESS != status)
17542 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17544 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017545 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017546 ret = -EINVAL;
17547 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017548 }
17549
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17551 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
17552 WAIT_TIME_TDLS_MGMT);
17553
Hoonki Leed37cbb32013-04-20 00:31:14 -070017554 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
17555 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
17556
17557 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017558 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070017559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070017560 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070017561 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017562 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080017563
17564 if (pHddCtx->isLogpInProgress)
17565 {
17566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17567 "%s: LOGP in Progress. Ignore!!!", __func__);
17568 return -EAGAIN;
17569 }
Abhishek Singh837adf22015-10-01 17:37:37 +053017570 if (rc <= 0)
17571 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
17572 WLAN_LOG_INDICATOR_HOST_DRIVER,
17573 WLAN_LOG_REASON_HDD_TIME_OUT,
17574 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080017575
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017576 ret = -EINVAL;
17577 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017578 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017579 else
17580 {
17581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17582 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
17583 __func__, rc, pAdapter->mgmtTxCompletionStatus);
17584 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017585
Gopichand Nakkala05922802013-03-14 12:23:19 -070017586 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070017587 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017588 ret = max_sta_failed;
17589 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070017590 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017591
Hoonki Leea34dd892013-02-05 22:56:02 -080017592 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
17593 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017594 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017595 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17596 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017597 }
17598 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
17599 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017600 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17602 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017603 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017604
17605 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017606
17607tx_failed:
17608 /* add_station will be called before sending TDLS_SETUP_REQ and
17609 * TDLS_SETUP_RSP and as part of add_station driver will enable
17610 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
17611 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
17612 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
17613 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
17614 */
17615
17616 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17617 (SIR_MAC_TDLS_SETUP_RSP == action_code))
17618 wlan_hdd_tdls_check_bmps(pAdapter);
17619 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017620}
17621
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017622#if TDLS_MGMT_VERSION2
17623static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17624 u8 *peer, u8 action_code, u8 dialog_token,
17625 u16 status_code, u32 peer_capability,
17626 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017627#else /* TDLS_MGMT_VERSION2 */
17628#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17629static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17630 struct net_device *dev,
17631 const u8 *peer, u8 action_code,
17632 u8 dialog_token, u16 status_code,
17633 u32 peer_capability, bool initiator,
17634 const u8 *buf, size_t len)
17635#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17636static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17637 struct net_device *dev,
17638 const u8 *peer, u8 action_code,
17639 u8 dialog_token, u16 status_code,
17640 u32 peer_capability, const u8 *buf,
17641 size_t len)
17642#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17643static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17644 struct net_device *dev,
17645 u8 *peer, u8 action_code,
17646 u8 dialog_token,
17647 u16 status_code, u32 peer_capability,
17648 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017649#else
17650static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17651 u8 *peer, u8 action_code, u8 dialog_token,
17652 u16 status_code, const u8 *buf, size_t len)
17653#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017654#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017655{
17656 int ret;
17657
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017658 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017659#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017660 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17661 dialog_token, status_code,
17662 peer_capability, buf, len);
17663#else /* TDLS_MGMT_VERSION2 */
17664#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17665 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17666 dialog_token, status_code,
17667 peer_capability, initiator,
17668 buf, len);
17669#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17670 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17671 dialog_token, status_code,
17672 peer_capability, buf, len);
17673#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17674 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17675 dialog_token, status_code,
17676 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017677#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017678 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17679 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017680#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017681#endif
17682 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017683
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017684 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017685}
Atul Mittal115287b2014-07-08 13:26:33 +053017686
17687int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017688#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17689 const u8 *peer,
17690#else
Atul Mittal115287b2014-07-08 13:26:33 +053017691 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017692#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017693 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053017694 cfg80211_exttdls_callback callback)
17695{
17696
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017697 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053017698 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017699 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053017700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17701 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
17702 __func__, MAC_ADDR_ARRAY(peer));
17703
17704 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17705 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17706
17707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017708 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17709 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17710 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017711 return -ENOTSUPP;
17712 }
17713
17714 /* To cater the requirement of establishing the TDLS link
17715 * irrespective of the data traffic , get an entry of TDLS peer.
17716 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017717 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017718 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
17719 if (pTdlsPeer == NULL) {
17720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17721 "%s: peer " MAC_ADDRESS_STR " not existing",
17722 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017723 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017724 return -EINVAL;
17725 }
17726
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017727 /* check FW TDLS Off Channel capability */
17728 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017729 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017730 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017731 {
17732 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
17733 pTdlsPeer->peerParams.global_operating_class =
17734 tdls_peer_params->global_operating_class;
17735 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
17736 pTdlsPeer->peerParams.min_bandwidth_kbps =
17737 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017738 /* check configured channel is valid, non dfs and
17739 * not current operating channel */
17740 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
17741 tdls_peer_params->channel)) &&
17742 (pHddStaCtx) &&
17743 (tdls_peer_params->channel !=
17744 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017745 {
17746 pTdlsPeer->isOffChannelConfigured = TRUE;
17747 }
17748 else
17749 {
17750 pTdlsPeer->isOffChannelConfigured = FALSE;
17751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17752 "%s: Configured Tdls Off Channel is not valid", __func__);
17753
17754 }
17755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017756 "%s: tdls_off_channel %d isOffChannelConfigured %d "
17757 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017758 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017759 pTdlsPeer->isOffChannelConfigured,
17760 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017761 }
17762 else
17763 {
17764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017765 "%s: TDLS off channel FW capability %d, "
17766 "host capab %d or Invalid TDLS Peer Params", __func__,
17767 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
17768 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017769 }
17770
Atul Mittal115287b2014-07-08 13:26:33 +053017771 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
17772
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017773 mutex_unlock(&pHddCtx->tdls_lock);
17774
Atul Mittal115287b2014-07-08 13:26:33 +053017775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17776 " %s TDLS Add Force Peer Failed",
17777 __func__);
17778 return -EINVAL;
17779 }
17780 /*EXT TDLS*/
17781
17782 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017783 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17785 " %s TDLS set callback Failed",
17786 __func__);
17787 return -EINVAL;
17788 }
17789
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017790 mutex_unlock(&pHddCtx->tdls_lock);
17791
Atul Mittal115287b2014-07-08 13:26:33 +053017792 return(0);
17793
17794}
17795
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017796int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
17797#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17798 const u8 *peer
17799#else
17800 u8 *peer
17801#endif
17802)
Atul Mittal115287b2014-07-08 13:26:33 +053017803{
17804
17805 hddTdlsPeer_t *pTdlsPeer;
17806 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053017807
Atul Mittal115287b2014-07-08 13:26:33 +053017808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17809 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
17810 __func__, MAC_ADDR_ARRAY(peer));
17811
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017812 if (0 != wlan_hdd_validate_context(pHddCtx)) {
17813 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
17814 return -EINVAL;
17815 }
17816
Atul Mittal115287b2014-07-08 13:26:33 +053017817 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17818 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17819
17820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017821 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17822 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17823 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017824 return -ENOTSUPP;
17825 }
17826
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017827 mutex_lock(&pHddCtx->tdls_lock);
17828 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053017829
17830 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017831 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017832 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017833 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053017834 __func__, MAC_ADDR_ARRAY(peer));
17835 return -EINVAL;
17836 }
17837 else {
17838 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
17839 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053017840 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
17841 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017842 /* if channel switch is configured, reset
17843 the channel for this peer */
17844 if (TRUE == pTdlsPeer->isOffChannelConfigured)
17845 {
17846 pTdlsPeer->peerParams.channel = 0;
17847 pTdlsPeer->isOffChannelConfigured = FALSE;
17848 }
Atul Mittal115287b2014-07-08 13:26:33 +053017849 }
17850
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017851 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017852 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017853 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053017854 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017855 }
Atul Mittal115287b2014-07-08 13:26:33 +053017856
17857 /*EXT TDLS*/
17858
17859 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017860 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17862 " %s TDLS set callback Failed",
17863 __func__);
17864 return -EINVAL;
17865 }
Atul Mittal115287b2014-07-08 13:26:33 +053017866
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017867 mutex_unlock(&pHddCtx->tdls_lock);
17868
17869 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053017870}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017871static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017872#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17873 const u8 *peer,
17874#else
17875 u8 *peer,
17876#endif
17877 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017878{
17879 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17880 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017881 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017882 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017883
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017884 ENTER();
17885
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017886 if (!pAdapter) {
17887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17888 return -EINVAL;
17889 }
17890
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017891 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17892 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
17893 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017894 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017895 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070017897 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017898 return -EINVAL;
17899 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017900
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017901 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017902 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017903 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017904 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017905 }
17906
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017907
17908 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017909 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017910 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017912 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
17913 "Cannot process TDLS commands",
17914 pHddCtx->cfg_ini->fEnableTDLSSupport,
17915 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017916 return -ENOTSUPP;
17917 }
17918
17919 switch (oper) {
17920 case NL80211_TDLS_ENABLE_LINK:
17921 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017922 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017923 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053017924 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
17925 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053017926 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017927 tANI_U16 numCurrTdlsPeers = 0;
17928 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017929 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053017930 tSirMacAddr peerMac;
17931 int channel;
17932 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017933
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17935 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
17936 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017937
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053017938 mutex_lock(&pHddCtx->tdls_lock);
17939 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053017940 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053017941 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053017942 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053017943 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
17944 " (oper %d) not exsting. ignored",
17945 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
17946 return -EINVAL;
17947 }
17948
17949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17950 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
17951 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
17952 "NL80211_TDLS_ENABLE_LINK");
17953
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070017954 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
17955 {
17956 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
17957 MAC_ADDRESS_STR " failed",
17958 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053017959 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070017960 return -EINVAL;
17961 }
17962
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053017963 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053017964 /* before starting tdls connection, set tdls
17965 * off channel established status to default value */
17966 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053017967
17968 mutex_unlock(&pHddCtx->tdls_lock);
17969
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017970 /* TDLS Off Channel, Disable tdls channel switch,
17971 when there are more than one tdls link */
17972 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053017973 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017974 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053017975 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017976 /* get connected peer and send disable tdls off chan */
17977 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017978 if ((connPeer) &&
17979 (connPeer->isOffChannelSupported == TRUE) &&
17980 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017981 {
17982 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17983 "%s: More then one peer connected, Disable "
17984 "TDLS channel switch", __func__);
17985
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017986 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053017987 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
17988 channel = connPeer->peerParams.channel;
17989
17990 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017991
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017992 ret = sme_SendTdlsChanSwitchReq(
17993 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017994 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053017995 peerMac,
17996 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017997 TDLS_OFF_CHANNEL_BW_OFFSET,
17998 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017999 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018000 hddLog(VOS_TRACE_LEVEL_ERROR,
18001 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018002 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018003 }
18004 else
18005 {
18006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18007 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018008 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018009 "isOffChannelConfigured %d",
18010 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018011 (connPeer ? (connPeer->isOffChannelSupported)
18012 : -1),
18013 (connPeer ? (connPeer->isOffChannelConfigured)
18014 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018015 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018016 }
18017 }
18018
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018019 mutex_lock(&pHddCtx->tdls_lock);
18020 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18021 if ( NULL == pTdlsPeer ) {
18022 mutex_unlock(&pHddCtx->tdls_lock);
18023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18024 "%s: " MAC_ADDRESS_STR
18025 " (oper %d) peer got freed in other context. ignored",
18026 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18027 return -EINVAL;
18028 }
18029 peer_status = pTdlsPeer->link_status;
18030 mutex_unlock(&pHddCtx->tdls_lock);
18031
18032 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018033 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018034 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053018035
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018036 if (0 != wlan_hdd_tdls_get_link_establish_params(
18037 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018038 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018039 return -EINVAL;
18040 }
18041 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018042
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018043 ret = sme_SendTdlsLinkEstablishParams(
18044 WLAN_HDD_GET_HAL_CTX(pAdapter),
18045 pAdapter->sessionId, peer,
18046 &tdlsLinkEstablishParams);
18047 if (ret != VOS_STATUS_SUCCESS) {
18048 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
18049 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018050 /* Send TDLS peer UAPSD capabilities to the firmware and
18051 * register with the TL on after the response for this operation
18052 * is received .
18053 */
18054 ret = wait_for_completion_interruptible_timeout(
18055 &pAdapter->tdls_link_establish_req_comp,
18056 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053018057
18058 mutex_lock(&pHddCtx->tdls_lock);
18059 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18060 if ( NULL == pTdlsPeer ) {
18061 mutex_unlock(&pHddCtx->tdls_lock);
18062 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18063 "%s %d: " MAC_ADDRESS_STR
18064 " (oper %d) peer got freed in other context. ignored",
18065 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
18066 (int)oper);
18067 return -EINVAL;
18068 }
18069 peer_status = pTdlsPeer->link_status;
18070 mutex_unlock(&pHddCtx->tdls_lock);
18071
18072 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018073 {
18074 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018075 FL("Link Establish Request Failed Status %ld"),
18076 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018077 return -EINVAL;
18078 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018079 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018080
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018081 mutex_lock(&pHddCtx->tdls_lock);
18082 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18083 if ( NULL == pTdlsPeer ) {
18084 mutex_unlock(&pHddCtx->tdls_lock);
18085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18086 "%s: " MAC_ADDRESS_STR
18087 " (oper %d) peer got freed in other context. ignored",
18088 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18089 return -EINVAL;
18090 }
18091
Atul Mittal115287b2014-07-08 13:26:33 +053018092 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18093 eTDLS_LINK_CONNECTED,
18094 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018095 staDesc.ucSTAId = pTdlsPeer->staId;
18096 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053018097
18098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18099 "%s: tdlsLinkEstablishParams of peer "
18100 MAC_ADDRESS_STR "uapsdQueues: %d"
18101 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
18102 "isResponder: %d peerstaId: %d",
18103 __func__,
18104 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
18105 tdlsLinkEstablishParams.uapsdQueues,
18106 tdlsLinkEstablishParams.qos,
18107 tdlsLinkEstablishParams.maxSp,
18108 tdlsLinkEstablishParams.isBufSta,
18109 tdlsLinkEstablishParams.isOffChannelSupported,
18110 tdlsLinkEstablishParams.isResponder,
18111 pTdlsPeer->staId);
18112
18113 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18114 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
18115 __func__,
18116 staDesc.ucSTAId,
18117 staDesc.ucQosEnabled);
18118
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018119 ret = WLANTL_UpdateTdlsSTAClient(
18120 pHddCtx->pvosContext,
18121 &staDesc);
18122 if (ret != VOS_STATUS_SUCCESS) {
18123 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
18124 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053018125
Gopichand Nakkala471708b2013-06-04 20:03:01 +053018126 /* Mark TDLS client Authenticated .*/
18127 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
18128 pTdlsPeer->staId,
18129 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018130 if (VOS_STATUS_SUCCESS == status)
18131 {
Hoonki Lee14621352013-04-16 17:51:19 -070018132 if (pTdlsPeer->is_responder == 0)
18133 {
18134 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018135 tdlsConnInfo_t *tdlsInfo;
18136
18137 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
18138
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018139 if (!vos_timer_is_initialized(
18140 &pTdlsPeer->initiatorWaitTimeoutTimer))
18141 {
18142 /* Initialize initiator wait callback */
18143 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018144 &pTdlsPeer->initiatorWaitTimeoutTimer,
18145 VOS_TIMER_TYPE_SW,
18146 wlan_hdd_tdls_initiator_wait_cb,
18147 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018148 }
Hoonki Lee14621352013-04-16 17:51:19 -070018149 wlan_hdd_tdls_timer_restart(pAdapter,
18150 &pTdlsPeer->initiatorWaitTimeoutTimer,
18151 WAIT_TIME_TDLS_INITIATOR);
18152 /* suspend initiator TX until it receives direct packet from the
18153 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018154 ret = WLANTL_SuspendDataTx(
18155 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18156 &staId, NULL);
18157 if (ret != VOS_STATUS_SUCCESS) {
18158 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
18159 }
Hoonki Lee14621352013-04-16 17:51:19 -070018160 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018161
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018162 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018163 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018164 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018165 suppChannelLen =
18166 tdlsLinkEstablishParams.supportedChannelsLen;
18167
18168 if ((suppChannelLen > 0) &&
18169 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
18170 {
18171 tANI_U8 suppPeerChannel = 0;
18172 int i = 0;
18173 for (i = 0U; i < suppChannelLen; i++)
18174 {
18175 suppPeerChannel =
18176 tdlsLinkEstablishParams.supportedChannels[i];
18177
18178 pTdlsPeer->isOffChannelSupported = FALSE;
18179 if (suppPeerChannel ==
18180 pTdlsPeer->peerParams.channel)
18181 {
18182 pTdlsPeer->isOffChannelSupported = TRUE;
18183 break;
18184 }
18185 }
18186 }
18187 else
18188 {
18189 pTdlsPeer->isOffChannelSupported = FALSE;
18190 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018191 }
18192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18193 "%s: TDLS channel switch request for channel "
18194 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018195 "%d isOffChannelSupported %d", __func__,
18196 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018197 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018198 suppChannelLen,
18199 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018200
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018201 /* TDLS Off Channel, Enable tdls channel switch,
18202 when their is only one tdls link and it supports */
18203 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18204 if ((numCurrTdlsPeers == 1) &&
18205 (TRUE == pTdlsPeer->isOffChannelSupported) &&
18206 (TRUE == pTdlsPeer->isOffChannelConfigured))
18207 {
18208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18209 "%s: Send TDLS channel switch request for channel %d",
18210 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018211
18212 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018213 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
18214 channel = pTdlsPeer->peerParams.channel;
18215
18216 mutex_unlock(&pHddCtx->tdls_lock);
18217
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018218 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
18219 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018220 peerMac,
18221 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018222 TDLS_OFF_CHANNEL_BW_OFFSET,
18223 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018224 if (ret != VOS_STATUS_SUCCESS) {
18225 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
18226 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018227 }
18228 else
18229 {
18230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18231 "%s: TDLS channel switch request not sent"
18232 " numCurrTdlsPeers %d "
18233 "isOffChannelSupported %d "
18234 "isOffChannelConfigured %d",
18235 __func__, numCurrTdlsPeers,
18236 pTdlsPeer->isOffChannelSupported,
18237 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018238 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018239 }
18240
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018241 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018242 else
18243 mutex_unlock(&pHddCtx->tdls_lock);
18244
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018245 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018246
18247 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018248 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18249 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018250 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018251 int ac;
18252 uint8 ucAc[4] = { WLANTL_AC_VO,
18253 WLANTL_AC_VI,
18254 WLANTL_AC_BK,
18255 WLANTL_AC_BE };
18256 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18257 for(ac=0; ac < 4; ac++)
18258 {
18259 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18260 pTdlsPeer->staId, ucAc[ac],
18261 tlTid[ac], tlTid[ac], 0, 0,
18262 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018263 if (status != VOS_STATUS_SUCCESS) {
18264 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18265 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018266 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018267 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018268 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018269
Bhargav Shah66896792015-10-01 18:17:37 +053018270 /* stop TCP delack timer if TDLS is enable */
18271 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18272 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053018273 hdd_wlan_tdls_enable_link_event(peer,
18274 pTdlsPeer->isOffChannelSupported,
18275 pTdlsPeer->isOffChannelConfigured,
18276 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018277 }
18278 break;
18279 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018280 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018281 tANI_U16 numCurrTdlsPeers = 0;
18282 hddTdlsPeer_t *connPeer = NULL;
18283
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018284 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18285 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18286 __func__, MAC_ADDR_ARRAY(peer));
18287
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018288 mutex_lock(&pHddCtx->tdls_lock);
18289 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018290
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018291
Sunil Dutt41de4e22013-11-14 18:09:02 +053018292 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018293 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018294 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18295 " (oper %d) not exsting. ignored",
18296 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18297 return -EINVAL;
18298 }
18299
18300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18301 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18302 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18303 "NL80211_TDLS_DISABLE_LINK");
18304
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018305 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018306 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018307 long status;
18308
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018309 /* set tdls off channel status to false for this peer */
18310 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018311 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18312 eTDLS_LINK_TEARING,
18313 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18314 eTDLS_LINK_UNSPECIFIED:
18315 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018316 mutex_unlock(&pHddCtx->tdls_lock);
18317
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018318 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18319
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018320 status = sme_DeleteTdlsPeerSta(
18321 WLAN_HDD_GET_HAL_CTX(pAdapter),
18322 pAdapter->sessionId, peer );
18323 if (status != VOS_STATUS_SUCCESS) {
18324 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18325 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018326
18327 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18328 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018329
18330 mutex_lock(&pHddCtx->tdls_lock);
18331 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18332 if ( NULL == pTdlsPeer ) {
18333 mutex_unlock(&pHddCtx->tdls_lock);
18334 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18335 " peer was freed in other context",
18336 __func__, MAC_ADDR_ARRAY(peer));
18337 return -EINVAL;
18338 }
18339
Atul Mittal271a7652014-09-12 13:18:22 +053018340 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053018341 eTDLS_LINK_IDLE,
18342 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018343 mutex_unlock(&pHddCtx->tdls_lock);
18344
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018345 if (status <= 0)
18346 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18348 "%s: Del station failed status %ld",
18349 __func__, status);
18350 return -EPERM;
18351 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018352
18353 /* TDLS Off Channel, Enable tdls channel switch,
18354 when their is only one tdls link and it supports */
18355 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18356 if (numCurrTdlsPeers == 1)
18357 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018358 tSirMacAddr peerMac;
18359 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018360
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018361 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018362 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018363
18364 if (connPeer == NULL) {
18365 mutex_unlock(&pHddCtx->tdls_lock);
18366 hddLog(VOS_TRACE_LEVEL_ERROR,
18367 "%s connPeer is NULL", __func__);
18368 return -EINVAL;
18369 }
18370
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018371 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18372 channel = connPeer->peerParams.channel;
18373
18374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18375 "%s: TDLS channel switch "
18376 "isOffChannelSupported %d "
18377 "isOffChannelConfigured %d "
18378 "isOffChannelEstablished %d",
18379 __func__,
18380 (connPeer ? connPeer->isOffChannelSupported : -1),
18381 (connPeer ? connPeer->isOffChannelConfigured : -1),
18382 (connPeer ? connPeer->isOffChannelEstablished : -1));
18383
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018384 if ((connPeer) &&
18385 (connPeer->isOffChannelSupported == TRUE) &&
18386 (connPeer->isOffChannelConfigured == TRUE))
18387 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018388 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018389 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018390 status = sme_SendTdlsChanSwitchReq(
18391 WLAN_HDD_GET_HAL_CTX(pAdapter),
18392 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018393 peerMac,
18394 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018395 TDLS_OFF_CHANNEL_BW_OFFSET,
18396 TDLS_CHANNEL_SWITCH_ENABLE);
18397 if (status != VOS_STATUS_SUCCESS) {
18398 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18399 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018400 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018401 else
18402 mutex_unlock(&pHddCtx->tdls_lock);
18403 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018404 else
18405 {
18406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18407 "%s: TDLS channel switch request not sent "
18408 "numCurrTdlsPeers %d ",
18409 __func__, numCurrTdlsPeers);
18410 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018411 }
18412 else
18413 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018414 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18416 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080018417 }
Bhargav Shah66896792015-10-01 18:17:37 +053018418 if (numCurrTdlsPeers == 0) {
18419 /* start TCP delack timer if TDLS is disable */
18420 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18421 hdd_manage_delack_timer(pHddCtx);
18422 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018423 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018424 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018425 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018426 {
Atul Mittal115287b2014-07-08 13:26:33 +053018427 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018428
Atul Mittal115287b2014-07-08 13:26:33 +053018429 if (0 != status)
18430 {
18431 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018432 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053018433 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018434 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053018435 break;
18436 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018437 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018438 {
Atul Mittal115287b2014-07-08 13:26:33 +053018439 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
18440 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018441 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053018442 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018443
Atul Mittal115287b2014-07-08 13:26:33 +053018444 if (0 != status)
18445 {
18446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018447 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053018448 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053018449 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053018450 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018451 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018452 case NL80211_TDLS_DISCOVERY_REQ:
18453 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018455 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018456 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018457 return -ENOTSUPP;
18458 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18460 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018461 return -ENOTSUPP;
18462 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018463
18464 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018465 return 0;
18466}
Chilam NG571c65a2013-01-19 12:27:36 +053018467
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018468static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018469#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18470 const u8 *peer,
18471#else
18472 u8 *peer,
18473#endif
18474 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018475{
18476 int ret;
18477
18478 vos_ssr_protect(__func__);
18479 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
18480 vos_ssr_unprotect(__func__);
18481
18482 return ret;
18483}
18484
Chilam NG571c65a2013-01-19 12:27:36 +053018485int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
18486 struct net_device *dev, u8 *peer)
18487{
Arif Hussaina7c8e412013-11-20 11:06:42 -080018488 hddLog(VOS_TRACE_LEVEL_INFO,
18489 "tdls send discover req: "MAC_ADDRESS_STR,
18490 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018491#if TDLS_MGMT_VERSION2
18492 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18493 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18494#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018495#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18496 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18497 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
18498#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18499 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18500 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18501#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18502 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18503 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18504#else
Chilam NG571c65a2013-01-19 12:27:36 +053018505 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18506 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018507#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018508#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053018509}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018510#endif
18511
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018512#ifdef WLAN_FEATURE_GTK_OFFLOAD
18513/*
18514 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
18515 * Callback rountine called upon receiving response for
18516 * get offload info
18517 */
18518void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
18519 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
18520{
18521
18522 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018523 tANI_U8 tempReplayCounter[8];
18524 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018525
18526 ENTER();
18527
18528 if (NULL == pAdapter)
18529 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018531 "%s: HDD adapter is Null", __func__);
18532 return ;
18533 }
18534
18535 if (NULL == pGtkOffloadGetInfoRsp)
18536 {
18537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18538 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
18539 return ;
18540 }
18541
18542 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
18543 {
18544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18545 "%s: wlan Failed to get replay counter value",
18546 __func__);
18547 return ;
18548 }
18549
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018550 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18551 /* Update replay counter */
18552 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
18553 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18554
18555 {
18556 /* changing from little to big endian since supplicant
18557 * works on big endian format
18558 */
18559 int i;
18560 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18561
18562 for (i = 0; i < 8; i++)
18563 {
18564 tempReplayCounter[7-i] = (tANI_U8)p[i];
18565 }
18566 }
18567
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018568 /* Update replay counter to NL */
18569 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018570 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018571}
18572
18573/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018574 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018575 * This function is used to offload GTK rekeying job to the firmware.
18576 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018577int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018578 struct cfg80211_gtk_rekey_data *data)
18579{
18580 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18581 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18582 hdd_station_ctx_t *pHddStaCtx;
18583 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018584 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018585 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018586 eHalStatus status = eHAL_STATUS_FAILURE;
18587
18588 ENTER();
18589
18590 if (NULL == pAdapter)
18591 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018593 "%s: HDD adapter is Null", __func__);
18594 return -ENODEV;
18595 }
18596
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018597 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18598 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
18599 pAdapter->sessionId, pAdapter->device_mode));
18600
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018601 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018602 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018603 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018604 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018605 }
18606
18607 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18608 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18609 if (NULL == hHal)
18610 {
18611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18612 "%s: HAL context is Null!!!", __func__);
18613 return -EAGAIN;
18614 }
18615
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018616 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
18617 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
18618 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
18619 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018620 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018621 {
18622 /* changing from big to little endian since driver
18623 * works on little endian format
18624 */
18625 tANI_U8 *p =
18626 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
18627 int i;
18628
18629 for (i = 0; i < 8; i++)
18630 {
18631 p[7-i] = data->replay_ctr[i];
18632 }
18633 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018634
18635 if (TRUE == pHddCtx->hdd_wlan_suspended)
18636 {
18637 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018638 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
18639 sizeof (tSirGtkOffloadParams));
18640 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018641 pAdapter->sessionId);
18642
18643 if (eHAL_STATUS_SUCCESS != status)
18644 {
18645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18646 "%s: sme_SetGTKOffload failed, returned %d",
18647 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018648
18649 /* Need to clear any trace of key value in the memory.
18650 * Thus zero out the memory even though it is local
18651 * variable.
18652 */
18653 vos_mem_zero(&hddGtkOffloadReqParams,
18654 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018655 return status;
18656 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18658 "%s: sme_SetGTKOffload successfull", __func__);
18659 }
18660 else
18661 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18663 "%s: wlan not suspended GTKOffload request is stored",
18664 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018665 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018666
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018667 /* Need to clear any trace of key value in the memory.
18668 * Thus zero out the memory even though it is local
18669 * variable.
18670 */
18671 vos_mem_zero(&hddGtkOffloadReqParams,
18672 sizeof(hddGtkOffloadReqParams));
18673
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018674 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018675 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018676}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018677
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018678int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
18679 struct cfg80211_gtk_rekey_data *data)
18680{
18681 int ret;
18682
18683 vos_ssr_protect(__func__);
18684 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
18685 vos_ssr_unprotect(__func__);
18686
18687 return ret;
18688}
18689#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018690/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018691 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018692 * This function is used to set access control policy
18693 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018694static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18695 struct net_device *dev,
18696 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018697{
18698 int i;
18699 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18700 hdd_hostapd_state_t *pHostapdState;
18701 tsap_Config_t *pConfig;
18702 v_CONTEXT_t pVosContext = NULL;
18703 hdd_context_t *pHddCtx;
18704 int status;
18705
18706 ENTER();
18707
18708 if (NULL == pAdapter)
18709 {
18710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18711 "%s: HDD adapter is Null", __func__);
18712 return -ENODEV;
18713 }
18714
18715 if (NULL == params)
18716 {
18717 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18718 "%s: params is Null", __func__);
18719 return -EINVAL;
18720 }
18721
18722 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18723 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018724 if (0 != status)
18725 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018726 return status;
18727 }
18728
18729 pVosContext = pHddCtx->pvosContext;
18730 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
18731
18732 if (NULL == pHostapdState)
18733 {
18734 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18735 "%s: pHostapdState is Null", __func__);
18736 return -EINVAL;
18737 }
18738
18739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
18740 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018741 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18742 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
18743 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018744
18745 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
18746 {
18747 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
18748
18749 /* default value */
18750 pConfig->num_accept_mac = 0;
18751 pConfig->num_deny_mac = 0;
18752
18753 /**
18754 * access control policy
18755 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
18756 * listed in hostapd.deny file.
18757 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
18758 * listed in hostapd.accept file.
18759 */
18760 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
18761 {
18762 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
18763 }
18764 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
18765 {
18766 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
18767 }
18768 else
18769 {
18770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18771 "%s:Acl Policy : %d is not supported",
18772 __func__, params->acl_policy);
18773 return -ENOTSUPP;
18774 }
18775
18776 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
18777 {
18778 pConfig->num_accept_mac = params->n_acl_entries;
18779 for (i = 0; i < params->n_acl_entries; i++)
18780 {
18781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18782 "** Add ACL MAC entry %i in WhiletList :"
18783 MAC_ADDRESS_STR, i,
18784 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18785
18786 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
18787 sizeof(qcmacaddr));
18788 }
18789 }
18790 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
18791 {
18792 pConfig->num_deny_mac = params->n_acl_entries;
18793 for (i = 0; i < params->n_acl_entries; i++)
18794 {
18795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18796 "** Add ACL MAC entry %i in BlackList :"
18797 MAC_ADDRESS_STR, i,
18798 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18799
18800 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
18801 sizeof(qcmacaddr));
18802 }
18803 }
18804
18805 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
18806 {
18807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18808 "%s: SAP Set Mac Acl fail", __func__);
18809 return -EINVAL;
18810 }
18811 }
18812 else
18813 {
18814 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053018815 "%s: Invalid device_mode = %s (%d)",
18816 __func__, hdd_device_modetoString(pAdapter->device_mode),
18817 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018818 return -EINVAL;
18819 }
18820
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018821 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018822 return 0;
18823}
18824
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018825static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18826 struct net_device *dev,
18827 const struct cfg80211_acl_data *params)
18828{
18829 int ret;
18830 vos_ssr_protect(__func__);
18831 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
18832 vos_ssr_unprotect(__func__);
18833
18834 return ret;
18835}
18836
Leo Chang9056f462013-08-01 19:21:11 -070018837#ifdef WLAN_NL80211_TESTMODE
18838#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070018839void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070018840(
18841 void *pAdapter,
18842 void *indCont
18843)
18844{
Leo Changd9df8aa2013-09-26 13:32:26 -070018845 tSirLPHBInd *lphbInd;
18846 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053018847 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070018848
18849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018850 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070018851
c_hpothu73f35e62014-04-18 13:40:08 +053018852 if (pAdapter == NULL)
18853 {
18854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18855 "%s: pAdapter is NULL\n",__func__);
18856 return;
18857 }
18858
Leo Chang9056f462013-08-01 19:21:11 -070018859 if (NULL == indCont)
18860 {
18861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018862 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070018863 return;
18864 }
18865
c_hpothu73f35e62014-04-18 13:40:08 +053018866 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070018867 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070018868 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053018869 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070018870 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070018871 GFP_ATOMIC);
18872 if (!skb)
18873 {
18874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18875 "LPHB timeout, NL buffer alloc fail");
18876 return;
18877 }
18878
Leo Changac3ba772013-10-07 09:47:04 -070018879 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070018880 {
18881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18882 "WLAN_HDD_TM_ATTR_CMD put fail");
18883 goto nla_put_failure;
18884 }
Leo Changac3ba772013-10-07 09:47:04 -070018885 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070018886 {
18887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18888 "WLAN_HDD_TM_ATTR_TYPE put fail");
18889 goto nla_put_failure;
18890 }
Leo Changac3ba772013-10-07 09:47:04 -070018891 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070018892 sizeof(tSirLPHBInd), lphbInd))
18893 {
18894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18895 "WLAN_HDD_TM_ATTR_DATA put fail");
18896 goto nla_put_failure;
18897 }
Leo Chang9056f462013-08-01 19:21:11 -070018898 cfg80211_testmode_event(skb, GFP_ATOMIC);
18899 return;
18900
18901nla_put_failure:
18902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18903 "NLA Put fail");
18904 kfree_skb(skb);
18905
18906 return;
18907}
18908#endif /* FEATURE_WLAN_LPHB */
18909
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018910static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070018911{
18912 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
18913 int err = 0;
18914#ifdef FEATURE_WLAN_LPHB
18915 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070018916 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018917
18918 ENTER();
18919
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018920 err = wlan_hdd_validate_context(pHddCtx);
18921 if (0 != err)
18922 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018923 return err;
18924 }
Leo Chang9056f462013-08-01 19:21:11 -070018925#endif /* FEATURE_WLAN_LPHB */
18926
18927 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
18928 if (err)
18929 {
18930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18931 "%s Testmode INV ATTR", __func__);
18932 return err;
18933 }
18934
18935 if (!tb[WLAN_HDD_TM_ATTR_CMD])
18936 {
18937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18938 "%s Testmode INV CMD", __func__);
18939 return -EINVAL;
18940 }
18941
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018942 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18943 TRACE_CODE_HDD_CFG80211_TESTMODE,
18944 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070018945 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
18946 {
18947#ifdef FEATURE_WLAN_LPHB
18948 /* Low Power Heartbeat configuration request */
18949 case WLAN_HDD_TM_CMD_WLAN_HB:
18950 {
18951 int buf_len;
18952 void *buf;
18953 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080018954 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070018955
18956 if (!tb[WLAN_HDD_TM_ATTR_DATA])
18957 {
18958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18959 "%s Testmode INV DATA", __func__);
18960 return -EINVAL;
18961 }
18962
18963 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
18964 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080018965
18966 hb_params_temp =(tSirLPHBReq *)buf;
18967 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
18968 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
18969 return -EINVAL;
18970
Leo Chang9056f462013-08-01 19:21:11 -070018971 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
18972 if (NULL == hb_params)
18973 {
18974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18975 "%s Request Buffer Alloc Fail", __func__);
18976 return -EINVAL;
18977 }
18978
18979 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070018980 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
18981 hb_params,
18982 wlan_hdd_cfg80211_lphb_ind_handler);
18983 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070018984 {
Leo Changd9df8aa2013-09-26 13:32:26 -070018985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18986 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070018987 vos_mem_free(hb_params);
18988 }
Leo Chang9056f462013-08-01 19:21:11 -070018989 return 0;
18990 }
18991#endif /* FEATURE_WLAN_LPHB */
18992 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18994 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070018995 return -EOPNOTSUPP;
18996 }
18997
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018998 EXIT();
18999 return err;
Leo Chang9056f462013-08-01 19:21:11 -070019000}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019001
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053019002static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
19003#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
19004 struct wireless_dev *wdev,
19005#endif
19006 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019007{
19008 int ret;
19009
19010 vos_ssr_protect(__func__);
19011 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
19012 vos_ssr_unprotect(__func__);
19013
19014 return ret;
19015}
Leo Chang9056f462013-08-01 19:21:11 -070019016#endif /* CONFIG_NL80211_TESTMODE */
19017
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019018static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019019 struct net_device *dev,
19020 int idx, struct survey_info *survey)
19021{
19022 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19023 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053019024 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019025 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053019026 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019027 v_S7_t snr,rssi;
19028 int status, i, j, filled = 0;
19029
19030 ENTER();
19031
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019032 if (NULL == pAdapter)
19033 {
19034 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19035 "%s: HDD adapter is Null", __func__);
19036 return -ENODEV;
19037 }
19038
19039 if (NULL == wiphy)
19040 {
19041 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19042 "%s: wiphy is Null", __func__);
19043 return -ENODEV;
19044 }
19045
19046 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19047 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019048 if (0 != status)
19049 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019050 return status;
19051 }
19052
Mihir Sheted9072e02013-08-21 17:02:29 +053019053 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19054
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019055 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053019056 0 != pAdapter->survey_idx ||
19057 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019058 {
19059 /* The survey dump ops when implemented completely is expected to
19060 * return a survey of all channels and the ops is called by the
19061 * kernel with incremental values of the argument 'idx' till it
19062 * returns -ENONET. But we can only support the survey for the
19063 * operating channel for now. survey_idx is used to track
19064 * that the ops is called only once and then return -ENONET for
19065 * the next iteration
19066 */
19067 pAdapter->survey_idx = 0;
19068 return -ENONET;
19069 }
19070
Mukul Sharma9d5233b2015-06-11 20:28:20 +053019071 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
19072 {
19073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19074 "%s: Roaming in progress, hence return ", __func__);
19075 return -ENONET;
19076 }
19077
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019078 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19079
19080 wlan_hdd_get_snr(pAdapter, &snr);
19081 wlan_hdd_get_rssi(pAdapter, &rssi);
19082
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019083 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19084 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
19085 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019086 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
19087 hdd_wlan_get_freq(channel, &freq);
19088
19089
19090 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
19091 {
19092 if (NULL == wiphy->bands[i])
19093 {
19094 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
19095 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
19096 continue;
19097 }
19098
19099 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
19100 {
19101 struct ieee80211_supported_band *band = wiphy->bands[i];
19102
19103 if (band->channels[j].center_freq == (v_U16_t)freq)
19104 {
19105 survey->channel = &band->channels[j];
19106 /* The Rx BDs contain SNR values in dB for the received frames
19107 * while the supplicant expects noise. So we calculate and
19108 * return the value of noise (dBm)
19109 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
19110 */
19111 survey->noise = rssi - snr;
19112 survey->filled = SURVEY_INFO_NOISE_DBM;
19113 filled = 1;
19114 }
19115 }
19116 }
19117
19118 if (filled)
19119 pAdapter->survey_idx = 1;
19120 else
19121 {
19122 pAdapter->survey_idx = 0;
19123 return -ENONET;
19124 }
19125
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019126 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019127 return 0;
19128}
19129
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019130static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
19131 struct net_device *dev,
19132 int idx, struct survey_info *survey)
19133{
19134 int ret;
19135
19136 vos_ssr_protect(__func__);
19137 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
19138 vos_ssr_unprotect(__func__);
19139
19140 return ret;
19141}
19142
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019143/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019144 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019145 * this is called when cfg80211 driver resume
19146 * driver updates latest sched_scan scan result(if any) to cfg80211 database
19147 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019148int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019149{
19150 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19151 hdd_adapter_t *pAdapter;
19152 hdd_adapter_list_node_t *pAdapterNode, *pNext;
19153 VOS_STATUS status = VOS_STATUS_SUCCESS;
19154
19155 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019156
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019157 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019158 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019159 return 0;
19160 }
19161
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019162 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
19163 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019164 spin_lock(&pHddCtx->schedScan_lock);
19165 pHddCtx->isWiphySuspended = FALSE;
19166 if (TRUE != pHddCtx->isSchedScanUpdatePending)
19167 {
19168 spin_unlock(&pHddCtx->schedScan_lock);
19169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19170 "%s: Return resume is not due to PNO indication", __func__);
19171 return 0;
19172 }
19173 // Reset flag to avoid updatating cfg80211 data old results again
19174 pHddCtx->isSchedScanUpdatePending = FALSE;
19175 spin_unlock(&pHddCtx->schedScan_lock);
19176
19177 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
19178
19179 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
19180 {
19181 pAdapter = pAdapterNode->pAdapter;
19182 if ( (NULL != pAdapter) &&
19183 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
19184 {
19185 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019186 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19188 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019189 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019190 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019191 {
19192 /* Acquire wakelock to handle the case where APP's tries to
19193 * suspend immediately after updating the scan results. Whis
19194 * results in app's is in suspended state and not able to
19195 * process the connect request to AP
19196 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053019197 hdd_prevent_suspend_timeout(2000,
19198 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019199 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019200 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019201
19202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19203 "%s : cfg80211 scan result database updated", __func__);
19204
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019205 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019206 return 0;
19207
19208 }
19209 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19210 pAdapterNode = pNext;
19211 }
19212
19213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19214 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019215 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019216 return 0;
19217}
19218
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019219int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
19220{
19221 int ret;
19222
19223 vos_ssr_protect(__func__);
19224 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
19225 vos_ssr_unprotect(__func__);
19226
19227 return ret;
19228}
19229
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019230/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019231 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019232 * this is called when cfg80211 driver suspends
19233 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019234int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019235 struct cfg80211_wowlan *wow)
19236{
19237 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019238 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019239
19240 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019241
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019242 ret = wlan_hdd_validate_context(pHddCtx);
19243 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019244 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019245 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019246 }
19247
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019248
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019249 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19250 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
19251 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019252 pHddCtx->isWiphySuspended = TRUE;
19253
19254 EXIT();
19255
19256 return 0;
19257}
19258
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019259int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19260 struct cfg80211_wowlan *wow)
19261{
19262 int ret;
19263
19264 vos_ssr_protect(__func__);
19265 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19266 vos_ssr_unprotect(__func__);
19267
19268 return ret;
19269}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019270
19271#ifdef FEATURE_OEM_DATA_SUPPORT
19272static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019273 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019274{
19275 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19276
19277 ENTER();
19278
19279 if (wlan_hdd_validate_context(pHddCtx)) {
19280 return;
19281 }
19282 if (!pMsg)
19283 {
19284 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
19285 return;
19286 }
19287
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019288 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019289
19290 EXIT();
19291 return;
19292
19293}
19294
19295void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019296 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019297{
19298 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19299
19300 ENTER();
19301
19302 if (wlan_hdd_validate_context(pHddCtx)) {
19303 return;
19304 }
19305
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019306 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019307
19308 switch(evType) {
19309 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019310 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019311 break;
19312 default:
19313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
19314 break;
19315 }
19316 EXIT();
19317}
19318#endif
19319
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019320/**
19321 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
19322 * @wiphy: Pointer to wiphy
19323 * @wdev: Pointer to wireless device structure
19324 *
19325 * This function is used to abort an ongoing scan
19326 *
19327 * Return: None
19328 */
19329static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19330 struct wireless_dev *wdev)
19331{
19332 struct net_device *dev = wdev->netdev;
19333 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
19334 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
19335 int ret;
19336
19337 ENTER();
19338
19339 if (NULL == adapter) {
19340 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
19341 return;
19342 }
19343
19344 ret = wlan_hdd_validate_context(hdd_ctx);
19345 if (0 != ret)
19346 return;
19347
19348 wlan_hdd_scan_abort(adapter);
19349
19350 return;
19351}
19352
19353/**
19354 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
19355 * @wiphy: Pointer to wiphy
19356 * @wdev: Pointer to wireless device structure
19357 *
19358 * Return: None
19359 */
19360void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19361 struct wireless_dev *wdev)
19362{
19363 vos_ssr_protect(__func__);
19364 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
19365 vos_ssr_unprotect(__func__);
19366
19367 return;
19368}
19369
Jeff Johnson295189b2012-06-20 16:38:30 -070019370/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019371static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070019372{
19373 .add_virtual_intf = wlan_hdd_add_virtual_intf,
19374 .del_virtual_intf = wlan_hdd_del_virtual_intf,
19375 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
19376 .change_station = wlan_hdd_change_station,
19377#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
19378 .add_beacon = wlan_hdd_cfg80211_add_beacon,
19379 .del_beacon = wlan_hdd_cfg80211_del_beacon,
19380 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019381#else
19382 .start_ap = wlan_hdd_cfg80211_start_ap,
19383 .change_beacon = wlan_hdd_cfg80211_change_beacon,
19384 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070019385#endif
19386 .change_bss = wlan_hdd_cfg80211_change_bss,
19387 .add_key = wlan_hdd_cfg80211_add_key,
19388 .get_key = wlan_hdd_cfg80211_get_key,
19389 .del_key = wlan_hdd_cfg80211_del_key,
19390 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019391#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070019392 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019393#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019394 .scan = wlan_hdd_cfg80211_scan,
19395 .connect = wlan_hdd_cfg80211_connect,
19396 .disconnect = wlan_hdd_cfg80211_disconnect,
19397 .join_ibss = wlan_hdd_cfg80211_join_ibss,
19398 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
19399 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
19400 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
19401 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070019402 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
19403 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053019404 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070019405#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19406 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
19407 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
19408 .set_txq_params = wlan_hdd_set_txq_params,
19409#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019410 .get_station = wlan_hdd_cfg80211_get_station,
19411 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
19412 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019413 .add_station = wlan_hdd_cfg80211_add_station,
19414#ifdef FEATURE_WLAN_LFR
19415 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
19416 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
19417 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
19418#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019419#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
19420 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
19421#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019422#ifdef FEATURE_WLAN_TDLS
19423 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
19424 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
19425#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019426#ifdef WLAN_FEATURE_GTK_OFFLOAD
19427 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
19428#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019429#ifdef FEATURE_WLAN_SCAN_PNO
19430 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
19431 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
19432#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019433 .resume = wlan_hdd_cfg80211_resume_wlan,
19434 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019435 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070019436#ifdef WLAN_NL80211_TESTMODE
19437 .testmode_cmd = wlan_hdd_cfg80211_testmode,
19438#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019439 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019440 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Jeff Johnson295189b2012-06-20 16:38:30 -070019441};
19442