blob: dc655c1cecbb5086fb15521a35883fbefd735d3f [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530100
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
102#define g_mode_rates_size (12)
103#define a_mode_rates_size (8)
104#define FREQ_BASE_80211G (2407)
105#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700106#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530107#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800109 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700110
111#define HDD2GHZCHAN(freq, chan, flag) { \
112 .band = IEEE80211_BAND_2GHZ, \
113 .center_freq = (freq), \
114 .hw_value = (chan),\
115 .flags = (flag), \
116 .max_antenna_gain = 0 ,\
117 .max_power = 30, \
118}
119
120#define HDD5GHZCHAN(freq, chan, flag) { \
121 .band = IEEE80211_BAND_5GHZ, \
122 .center_freq = (freq), \
123 .hw_value = (chan),\
124 .flags = (flag), \
125 .max_antenna_gain = 0 ,\
126 .max_power = 30, \
127}
128
129#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
130{\
131 .bitrate = rate, \
132 .hw_value = rate_id, \
133 .flags = flag, \
134}
135
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530136#ifdef WLAN_FEATURE_VOWIFI_11R
137#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
138#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
139#endif
140
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530141#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530142#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143
Sunil Duttc69bccb2014-05-26 21:30:20 +0530144#ifdef WLAN_FEATURE_LINK_LAYER_STATS
145/*
146 * Used to allocate the size of 4096 for the link layer stats.
147 * The size of 4096 is considered assuming that all data per
148 * respective event fit with in the limit.Please take a call
149 * on the limit based on the data requirements on link layer
150 * statistics.
151 */
152#define LL_STATS_EVENT_BUF_SIZE 4096
153#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530154#ifdef WLAN_FEATURE_EXTSCAN
155/*
156 * Used to allocate the size of 4096 for the EXTScan NL data.
157 * The size of 4096 is considered assuming that all data per
158 * respective event fit with in the limit.Please take a call
159 * on the limit based on the data requirements.
160 */
161
162#define EXTSCAN_EVENT_BUF_SIZE 4096
163#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
164#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530165
Atul Mittal115287b2014-07-08 13:26:33 +0530166/*EXT TDLS*/
167/*
168 * Used to allocate the size of 4096 for the TDLS.
169 * The size of 4096 is considered assuming that all data per
170 * respective event fit with in the limit.Please take a call
171 * on the limit based on the data requirements on link layer
172 * statistics.
173 */
174#define EXTTDLS_EVENT_BUF_SIZE 4096
175
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530176/*
177 * Values for Mac spoofing feature
178 *
179 */
180#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
181#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
182#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530183#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
184
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530185
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530186static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700187{
188 WLAN_CIPHER_SUITE_WEP40,
189 WLAN_CIPHER_SUITE_WEP104,
190 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800191#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700192#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
193 WLAN_CIPHER_SUITE_KRK,
194 WLAN_CIPHER_SUITE_CCMP,
195#else
196 WLAN_CIPHER_SUITE_CCMP,
197#endif
198#ifdef FEATURE_WLAN_WAPI
199 WLAN_CIPHER_SUITE_SMS4,
200#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700201#ifdef WLAN_FEATURE_11W
202 WLAN_CIPHER_SUITE_AES_CMAC,
203#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700204};
205
206static inline int is_broadcast_ether_addr(const u8 *addr)
207{
208 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
209 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
210}
211
Agrawal Ashish97dec502015-11-26 20:20:58 +0530212const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530213{
Jeff Johnson295189b2012-06-20 16:38:30 -0700214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2417, 2, 0) ,
216 HDD2GHZCHAN(2422, 3, 0) ,
217 HDD2GHZCHAN(2427, 4, 0) ,
218 HDD2GHZCHAN(2432, 5, 0) ,
219 HDD2GHZCHAN(2437, 6, 0) ,
220 HDD2GHZCHAN(2442, 7, 0) ,
221 HDD2GHZCHAN(2447, 8, 0) ,
222 HDD2GHZCHAN(2452, 9, 0) ,
223 HDD2GHZCHAN(2457, 10, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225 HDD2GHZCHAN(2467, 12, 0) ,
226 HDD2GHZCHAN(2472, 13, 0) ,
227 HDD2GHZCHAN(2484, 14, 0) ,
228};
229
Agrawal Ashish97dec502015-11-26 20:20:58 +0530230const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700231{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700232 HDD5GHZCHAN(4920, 240, 0) ,
233 HDD5GHZCHAN(4940, 244, 0) ,
234 HDD5GHZCHAN(4960, 248, 0) ,
235 HDD5GHZCHAN(4980, 252, 0) ,
236 HDD5GHZCHAN(5040, 208, 0) ,
237 HDD5GHZCHAN(5060, 212, 0) ,
238 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD5GHZCHAN(5180, 36, 0) ,
240 HDD5GHZCHAN(5200, 40, 0) ,
241 HDD5GHZCHAN(5220, 44, 0) ,
242 HDD5GHZCHAN(5240, 48, 0) ,
243 HDD5GHZCHAN(5260, 52, 0) ,
244 HDD5GHZCHAN(5280, 56, 0) ,
245 HDD5GHZCHAN(5300, 60, 0) ,
246 HDD5GHZCHAN(5320, 64, 0) ,
247 HDD5GHZCHAN(5500,100, 0) ,
248 HDD5GHZCHAN(5520,104, 0) ,
249 HDD5GHZCHAN(5540,108, 0) ,
250 HDD5GHZCHAN(5560,112, 0) ,
251 HDD5GHZCHAN(5580,116, 0) ,
252 HDD5GHZCHAN(5600,120, 0) ,
253 HDD5GHZCHAN(5620,124, 0) ,
254 HDD5GHZCHAN(5640,128, 0) ,
255 HDD5GHZCHAN(5660,132, 0) ,
256 HDD5GHZCHAN(5680,136, 0) ,
257 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800258#ifdef FEATURE_WLAN_CH144
259 HDD5GHZCHAN(5720,144, 0) ,
260#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 HDD5GHZCHAN(5745,149, 0) ,
262 HDD5GHZCHAN(5765,153, 0) ,
263 HDD5GHZCHAN(5785,157, 0) ,
264 HDD5GHZCHAN(5805,161, 0) ,
265 HDD5GHZCHAN(5825,165, 0) ,
266};
267
268static struct ieee80211_rate g_mode_rates[] =
269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530270 HDD_G_MODE_RATETAB(10, 0x1, 0),
271 HDD_G_MODE_RATETAB(20, 0x2, 0),
272 HDD_G_MODE_RATETAB(55, 0x4, 0),
273 HDD_G_MODE_RATETAB(110, 0x8, 0),
274 HDD_G_MODE_RATETAB(60, 0x10, 0),
275 HDD_G_MODE_RATETAB(90, 0x20, 0),
276 HDD_G_MODE_RATETAB(120, 0x40, 0),
277 HDD_G_MODE_RATETAB(180, 0x80, 0),
278 HDD_G_MODE_RATETAB(240, 0x100, 0),
279 HDD_G_MODE_RATETAB(360, 0x200, 0),
280 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282};
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
284static struct ieee80211_rate a_mode_rates[] =
285{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530286 HDD_G_MODE_RATETAB(60, 0x10, 0),
287 HDD_G_MODE_RATETAB(90, 0x20, 0),
288 HDD_G_MODE_RATETAB(120, 0x40, 0),
289 HDD_G_MODE_RATETAB(180, 0x80, 0),
290 HDD_G_MODE_RATETAB(240, 0x100, 0),
291 HDD_G_MODE_RATETAB(360, 0x200, 0),
292 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 HDD_G_MODE_RATETAB(540, 0x800, 0),
294};
295
296static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
297{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530298 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700299 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
300 .band = IEEE80211_BAND_2GHZ,
301 .bitrates = g_mode_rates,
302 .n_bitrates = g_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
308 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
309 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
310 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
311 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
312 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
313};
314
Jeff Johnson295189b2012-06-20 16:38:30 -0700315static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
316{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530317 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
319 .band = IEEE80211_BAND_5GHZ,
320 .bitrates = a_mode_rates,
321 .n_bitrates = a_mode_rates_size,
322 .ht_cap.ht_supported = 1,
323 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
324 | IEEE80211_HT_CAP_GRN_FLD
325 | IEEE80211_HT_CAP_DSSSCCK40
326 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
327 | IEEE80211_HT_CAP_SGI_40
328 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
329 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
330 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
331 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
332 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
333 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
334};
335
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530336/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 TX/RX direction for each kind of interface */
338static const struct ieee80211_txrx_stypes
339wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
340 [NL80211_IFTYPE_STATION] = {
341 .tx = 0xffff,
342 .rx = BIT(SIR_MAC_MGMT_ACTION) |
343 BIT(SIR_MAC_MGMT_PROBE_REQ),
344 },
345 [NL80211_IFTYPE_AP] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
348 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
349 BIT(SIR_MAC_MGMT_PROBE_REQ) |
350 BIT(SIR_MAC_MGMT_DISASSOC) |
351 BIT(SIR_MAC_MGMT_AUTH) |
352 BIT(SIR_MAC_MGMT_DEAUTH) |
353 BIT(SIR_MAC_MGMT_ACTION),
354 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700355 [NL80211_IFTYPE_ADHOC] = {
356 .tx = 0xffff,
357 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
358 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
359 BIT(SIR_MAC_MGMT_PROBE_REQ) |
360 BIT(SIR_MAC_MGMT_DISASSOC) |
361 BIT(SIR_MAC_MGMT_AUTH) |
362 BIT(SIR_MAC_MGMT_DEAUTH) |
363 BIT(SIR_MAC_MGMT_ACTION),
364 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 [NL80211_IFTYPE_P2P_CLIENT] = {
366 .tx = 0xffff,
367 .rx = BIT(SIR_MAC_MGMT_ACTION) |
368 BIT(SIR_MAC_MGMT_PROBE_REQ),
369 },
370 [NL80211_IFTYPE_P2P_GO] = {
371 /* This is also same as for SoftAP */
372 .tx = 0xffff,
373 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ) |
376 BIT(SIR_MAC_MGMT_DISASSOC) |
377 BIT(SIR_MAC_MGMT_AUTH) |
378 BIT(SIR_MAC_MGMT_DEAUTH) |
379 BIT(SIR_MAC_MGMT_ACTION),
380 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700381};
382
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800383#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800384static const struct ieee80211_iface_limit
385wlan_hdd_iface_limit[] = {
386 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800387 /* max = 3 ; Our driver create two interfaces during driver init
388 * wlan0 and p2p0 interfaces. p2p0 is considered as station
389 * interface until a group is formed. In JB architecture, once the
390 * group is formed, interface type of p2p0 is changed to P2P GO or
391 * Client.
392 * When supplicant remove the group, it first issue a set interface
393 * cmd to change the mode back to Station. In JB this works fine as
394 * we advertize two station type interface during driver init.
395 * Some vendors create separate interface for P2P GO/Client,
396 * after group formation(Third one). But while group remove
397 * supplicant first tries to change the mode(3rd interface) to STATION
398 * But as we advertized only two sta type interfaces nl80211 was
399 * returning error for the third one which was leading to failure in
400 * delete interface. Ideally while removing the group, supplicant
401 * should not try to change the 3rd interface mode to Station type.
402 * Till we get a fix in wpa_supplicant, we advertize max STA
403 * interface type to 3
404 */
405 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800406 .types = BIT(NL80211_IFTYPE_STATION),
407 },
408 {
409 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700410 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 },
412 {
413 .max = 1,
414 .types = BIT(NL80211_IFTYPE_P2P_GO) |
415 BIT(NL80211_IFTYPE_P2P_CLIENT),
416 },
417};
418
419/* By default, only single channel concurrency is allowed */
420static struct ieee80211_iface_combination
421wlan_hdd_iface_combination = {
422 .limits = wlan_hdd_iface_limit,
423 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800424 /*
425 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
426 * and p2p0 interfaces during driver init
427 * Some vendors create separate interface for P2P operations.
428 * wlan0: STA interface
429 * p2p0: P2P Device interface, action frames goes
430 * through this interface.
431 * p2p-xx: P2P interface, After GO negotiation this interface is
432 * created for p2p operations(GO/CLIENT interface).
433 */
434 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800435 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
436 .beacon_int_infra_match = false,
437};
438#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800439
Jeff Johnson295189b2012-06-20 16:38:30 -0700440static struct cfg80211_ops wlan_hdd_cfg80211_ops;
441
442/* Data rate 100KBPS based on IE Index */
443struct index_data_rate_type
444{
445 v_U8_t beacon_rate_index;
446 v_U16_t supported_rate[4];
447};
448
449/* 11B, 11G Rate table include Basic rate and Extended rate
450 The IDX field is the rate index
451 The HI field is the rate when RSSI is strong or being ignored
452 (in this case we report actual rate)
453 The MID field is the rate when RSSI is moderate
454 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
455 The LO field is the rate when RSSI is low
456 (in this case we don't report rates, actual current rate used)
457 */
458static const struct
459{
460 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700461 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700462} supported_data_rate[] =
463{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700464/* IDX HI HM LM LO (RSSI-based index */
465 {2, { 10, 10, 10, 0}},
466 {4, { 20, 20, 10, 0}},
467 {11, { 55, 20, 10, 0}},
468 {12, { 60, 55, 20, 0}},
469 {18, { 90, 55, 20, 0}},
470 {22, {110, 55, 20, 0}},
471 {24, {120, 90, 60, 0}},
472 {36, {180, 120, 60, 0}},
473 {44, {220, 180, 60, 0}},
474 {48, {240, 180, 90, 0}},
475 {66, {330, 180, 90, 0}},
476 {72, {360, 240, 90, 0}},
477 {96, {480, 240, 120, 0}},
478 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700479};
480
481/* MCS Based rate table */
482static struct index_data_rate_type supported_mcs_rate[] =
483{
484/* MCS L20 L40 S20 S40 */
485 {0, {65, 135, 72, 150}},
486 {1, {130, 270, 144, 300}},
487 {2, {195, 405, 217, 450}},
488 {3, {260, 540, 289, 600}},
489 {4, {390, 810, 433, 900}},
490 {5, {520, 1080, 578, 1200}},
491 {6, {585, 1215, 650, 1350}},
492 {7, {650, 1350, 722, 1500}}
493};
494
Leo Chang6f8870f2013-03-26 18:11:36 -0700495#ifdef WLAN_FEATURE_11AC
496
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530497#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700498
499struct index_vht_data_rate_type
500{
501 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530502 v_U16_t supported_VHT80_rate[2];
503 v_U16_t supported_VHT40_rate[2];
504 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700505};
506
507typedef enum
508{
509 DATA_RATE_11AC_MAX_MCS_7,
510 DATA_RATE_11AC_MAX_MCS_8,
511 DATA_RATE_11AC_MAX_MCS_9,
512 DATA_RATE_11AC_MAX_MCS_NA
513} eDataRate11ACMaxMcs;
514
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530515/* SSID broadcast type */
516typedef enum eSSIDBcastType
517{
518 eBCAST_UNKNOWN = 0,
519 eBCAST_NORMAL = 1,
520 eBCAST_HIDDEN = 2,
521} tSSIDBcastType;
522
Leo Chang6f8870f2013-03-26 18:11:36 -0700523/* MCS Based VHT rate table */
524static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
525{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530526/* MCS L80 S80 L40 S40 L20 S40*/
527 {0, {293, 325}, {135, 150}, {65, 72}},
528 {1, {585, 650}, {270, 300}, {130, 144}},
529 {2, {878, 975}, {405, 450}, {195, 217}},
530 {3, {1170, 1300}, {540, 600}, {260, 289}},
531 {4, {1755, 1950}, {810, 900}, {390, 433}},
532 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
533 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
534 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
535 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
536 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700537};
538#endif /* WLAN_FEATURE_11AC */
539
c_hpothu79aab322014-07-14 21:11:01 +0530540/*array index points to MCS and array value points respective rssi*/
541static int rssiMcsTbl[][10] =
542{
543/*MCS 0 1 2 3 4 5 6 7 8 9*/
544 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
545 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
546 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
547};
548
Jeff Johnson295189b2012-06-20 16:38:30 -0700549extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530550#ifdef FEATURE_WLAN_SCAN_PNO
551static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
552#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700553
Leo Chang9056f462013-08-01 19:21:11 -0700554#ifdef WLAN_NL80211_TESTMODE
555enum wlan_hdd_tm_attr
556{
557 WLAN_HDD_TM_ATTR_INVALID = 0,
558 WLAN_HDD_TM_ATTR_CMD = 1,
559 WLAN_HDD_TM_ATTR_DATA = 2,
560 WLAN_HDD_TM_ATTR_TYPE = 3,
561 /* keep last */
562 WLAN_HDD_TM_ATTR_AFTER_LAST,
563 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
564};
565
566enum wlan_hdd_tm_cmd
567{
568 WLAN_HDD_TM_CMD_WLAN_HB = 1,
569};
570
571#define WLAN_HDD_TM_DATA_MAX_LEN 5000
572
573static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
574{
575 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
576 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
577 .len = WLAN_HDD_TM_DATA_MAX_LEN },
578};
579#endif /* WLAN_NL80211_TESTMODE */
580
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800581#ifdef FEATURE_WLAN_CH_AVOID
582/*
583 * FUNCTION: wlan_hdd_send_avoid_freq_event
584 * This is called when wlan driver needs to send vendor specific
585 * avoid frequency range event to userspace
586 */
587int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
588 tHddAvoidFreqList *pAvoidFreqList)
589{
590 struct sk_buff *vendor_event;
591
592 ENTER();
593
594 if (!pHddCtx)
595 {
596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
597 "%s: HDD context is null", __func__);
598 return -1;
599 }
600
601 if (!pAvoidFreqList)
602 {
603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
604 "%s: pAvoidFreqList is null", __func__);
605 return -1;
606 }
607
608 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530609#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
610 NULL,
611#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800612 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530613 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800614 GFP_KERNEL);
615 if (!vendor_event)
616 {
617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
618 "%s: cfg80211_vendor_event_alloc failed", __func__);
619 return -1;
620 }
621
622 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
623 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
624
625 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
626
627 EXIT();
628 return 0;
629}
630#endif /* FEATURE_WLAN_CH_AVOID */
631
Srinivas Dasari030bad32015-02-18 23:23:54 +0530632/*
633 * FUNCTION: __wlan_hdd_cfg80211_nan_request
634 * This is called when wlan driver needs to send vendor specific
635 * nan request event.
636 */
637static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
638 struct wireless_dev *wdev,
639 const void *data, int data_len)
640{
641 tNanRequestReq nan_req;
642 VOS_STATUS status;
643 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530644 struct net_device *dev = wdev->netdev;
645 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
646 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530647 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
648
649 if (0 == data_len)
650 {
651 hddLog(VOS_TRACE_LEVEL_ERROR,
652 FL("NAN - Invalid Request, length = 0"));
653 return ret_val;
654 }
655
656 if (NULL == data)
657 {
658 hddLog(VOS_TRACE_LEVEL_ERROR,
659 FL("NAN - Invalid Request, data is NULL"));
660 return ret_val;
661 }
662
663 status = wlan_hdd_validate_context(pHddCtx);
664 if (0 != status)
665 {
666 hddLog(VOS_TRACE_LEVEL_ERROR,
667 FL("HDD context is not valid"));
668 return -EINVAL;
669 }
670
671 hddLog(LOG1, FL("Received NAN command"));
672 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
673 (tANI_U8 *)data, data_len);
674
675 /* check the NAN Capability */
676 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
677 {
678 hddLog(VOS_TRACE_LEVEL_ERROR,
679 FL("NAN is not supported by Firmware"));
680 return -EINVAL;
681 }
682
683 nan_req.request_data_len = data_len;
684 nan_req.request_data = data;
685
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530686 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530687 if (VOS_STATUS_SUCCESS == status)
688 {
689 ret_val = 0;
690 }
691 return ret_val;
692}
693
694/*
695 * FUNCTION: wlan_hdd_cfg80211_nan_request
696 * Wrapper to protect the nan vendor command from ssr
697 */
698static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
699 struct wireless_dev *wdev,
700 const void *data, int data_len)
701{
702 int ret;
703
704 vos_ssr_protect(__func__);
705 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
706 vos_ssr_unprotect(__func__);
707
708 return ret;
709}
710
711/*
712 * FUNCTION: wlan_hdd_cfg80211_nan_callback
713 * This is a callback function and it gets called
714 * when we need to report nan response event to
715 * upper layers.
716 */
717static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
718{
719 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
720 struct sk_buff *vendor_event;
721 int status;
722 tSirNanEvent *data;
723
724 ENTER();
725 if (NULL == msg)
726 {
727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
728 FL(" msg received here is null"));
729 return;
730 }
731 data = msg;
732
733 status = wlan_hdd_validate_context(pHddCtx);
734
735 if (0 != status)
736 {
737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
738 FL("HDD context is not valid"));
739 return;
740 }
741
742 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530743#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
744 NULL,
745#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530746 data->event_data_len +
747 NLMSG_HDRLEN,
748 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
749 GFP_KERNEL);
750
751 if (!vendor_event)
752 {
753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
754 FL("cfg80211_vendor_event_alloc failed"));
755 return;
756 }
757 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
758 data->event_data_len, data->event_data))
759 {
760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
761 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
762 kfree_skb(vendor_event);
763 return;
764 }
765 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
766 EXIT();
767}
768
769/*
770 * FUNCTION: wlan_hdd_cfg80211_nan_init
771 * This function is called to register the callback to sme layer
772 */
773inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
774{
775 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
776}
777
778
Sunil Duttc69bccb2014-05-26 21:30:20 +0530779#ifdef WLAN_FEATURE_LINK_LAYER_STATS
780
781static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
782 struct sk_buff *vendor_event)
783{
784 if (nla_put_u8(vendor_event,
785 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
786 stats->rate.preamble) ||
787 nla_put_u8(vendor_event,
788 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
789 stats->rate.nss) ||
790 nla_put_u8(vendor_event,
791 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
792 stats->rate.bw) ||
793 nla_put_u8(vendor_event,
794 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
795 stats->rate.rateMcsIdx) ||
796 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
797 stats->rate.bitrate ) ||
798 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
799 stats->txMpdu ) ||
800 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
801 stats->rxMpdu ) ||
802 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
803 stats->mpduLost ) ||
804 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
805 stats->retries) ||
806 nla_put_u32(vendor_event,
807 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
808 stats->retriesShort ) ||
809 nla_put_u32(vendor_event,
810 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
811 stats->retriesLong))
812 {
813 hddLog(VOS_TRACE_LEVEL_ERROR,
814 FL("QCA_WLAN_VENDOR_ATTR put fail"));
815 return FALSE;
816 }
817 return TRUE;
818}
819
820static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
821 struct sk_buff *vendor_event)
822{
823 u32 i = 0;
824 struct nlattr *rateInfo;
825 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
826 stats->type) ||
827 nla_put(vendor_event,
828 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
829 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
830 nla_put_u32(vendor_event,
831 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
832 stats->capabilities) ||
833 nla_put_u32(vendor_event,
834 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
835 stats->numRate))
836 {
837 hddLog(VOS_TRACE_LEVEL_ERROR,
838 FL("QCA_WLAN_VENDOR_ATTR put fail"));
839 goto error;
840 }
841
842 rateInfo = nla_nest_start(vendor_event,
843 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530844 if(!rateInfo)
845 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530846 for (i = 0; i < stats->numRate; i++)
847 {
848 struct nlattr *rates;
849 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
850 stats->rateStats +
851 (i * sizeof(tSirWifiRateStat)));
852 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530853 if(!rates)
854 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530855
856 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
857 {
858 hddLog(VOS_TRACE_LEVEL_ERROR,
859 FL("QCA_WLAN_VENDOR_ATTR put fail"));
860 return FALSE;
861 }
862 nla_nest_end(vendor_event, rates);
863 }
864 nla_nest_end(vendor_event, rateInfo);
865
866 return TRUE;
867error:
868 return FALSE;
869}
870
871static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
872 struct sk_buff *vendor_event)
873{
874 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
875 stats->ac ) ||
876 nla_put_u32(vendor_event,
877 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
878 stats->txMpdu ) ||
879 nla_put_u32(vendor_event,
880 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
881 stats->rxMpdu ) ||
882 nla_put_u32(vendor_event,
883 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
884 stats->txMcast ) ||
885 nla_put_u32(vendor_event,
886 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
887 stats->rxMcast ) ||
888 nla_put_u32(vendor_event,
889 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
890 stats->rxAmpdu ) ||
891 nla_put_u32(vendor_event,
892 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
893 stats->txAmpdu ) ||
894 nla_put_u32(vendor_event,
895 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
896 stats->mpduLost )||
897 nla_put_u32(vendor_event,
898 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
899 stats->retries ) ||
900 nla_put_u32(vendor_event,
901 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
902 stats->retriesShort ) ||
903 nla_put_u32(vendor_event,
904 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
905 stats->retriesLong ) ||
906 nla_put_u32(vendor_event,
907 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
908 stats->contentionTimeMin ) ||
909 nla_put_u32(vendor_event,
910 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
911 stats->contentionTimeMax ) ||
912 nla_put_u32(vendor_event,
913 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
914 stats->contentionTimeAvg ) ||
915 nla_put_u32(vendor_event,
916 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
917 stats->contentionNumSamples ))
918 {
919 hddLog(VOS_TRACE_LEVEL_ERROR,
920 FL("QCA_WLAN_VENDOR_ATTR put fail") );
921 return FALSE;
922 }
923 return TRUE;
924}
925
926static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
927 struct sk_buff *vendor_event)
928{
Dino Myclec8f3f332014-07-21 16:48:27 +0530929 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530930 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
931 nla_put(vendor_event,
932 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
933 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
934 nla_put_u32(vendor_event,
935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
936 stats->state ) ||
937 nla_put_u32(vendor_event,
938 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
939 stats->roaming ) ||
940 nla_put_u32(vendor_event,
941 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
942 stats->capabilities ) ||
943 nla_put(vendor_event,
944 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
945 strlen(stats->ssid), stats->ssid) ||
946 nla_put(vendor_event,
947 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
948 WNI_CFG_BSSID_LEN, stats->bssid) ||
949 nla_put(vendor_event,
950 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
951 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
952 nla_put(vendor_event,
953 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
954 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
955 )
956 {
957 hddLog(VOS_TRACE_LEVEL_ERROR,
958 FL("QCA_WLAN_VENDOR_ATTR put fail") );
959 return FALSE;
960 }
961 return TRUE;
962}
963
Dino Mycle3b9536d2014-07-09 22:05:24 +0530964static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
965 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530966 struct sk_buff *vendor_event)
967{
968 int i = 0;
969 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530970 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
971 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530972 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530973
Sunil Duttc69bccb2014-05-26 21:30:20 +0530974 if (FALSE == put_wifi_interface_info(
975 &pWifiIfaceStat->info,
976 vendor_event))
977 {
978 hddLog(VOS_TRACE_LEVEL_ERROR,
979 FL("QCA_WLAN_VENDOR_ATTR put fail") );
980 return FALSE;
981
982 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530983 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
984 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
985 if (NULL == pWifiIfaceStatTL)
986 {
987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
988 return FALSE;
989 }
990
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530991 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
992 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
993 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
994 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
995
996 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
997 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
998 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
999 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301000
1001 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1002 {
1003 if (VOS_STATUS_SUCCESS ==
1004 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1005 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1006 {
1007 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1008 * obtained from TL structure
1009 */
1010
1011 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1012 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301013 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1014
Srinivas Dasari98947432014-11-07 19:41:24 +05301015 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1016 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1017 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1018 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1019 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1020 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1021 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1022 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301023
Srinivas Dasari98947432014-11-07 19:41:24 +05301024 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1025 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1026 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1027 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1028 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1029 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1030 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1031 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301032
Srinivas Dasari98947432014-11-07 19:41:24 +05301033 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1034 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1035 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1036 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1037 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1038 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1039 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1040 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301041 }
1042 else
1043 {
1044 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1045 }
1046
Dino Mycle3b9536d2014-07-09 22:05:24 +05301047 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1048 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1049 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1050 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1051 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1052 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1053 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1054 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1055 }
1056 else
1057 {
1058 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1059 }
1060
1061
Sunil Duttc69bccb2014-05-26 21:30:20 +05301062
1063 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301064 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1065 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1066 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301067 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1068 pWifiIfaceStat->beaconRx) ||
1069 nla_put_u32(vendor_event,
1070 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1071 pWifiIfaceStat->mgmtRx) ||
1072 nla_put_u32(vendor_event,
1073 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1074 pWifiIfaceStat->mgmtActionRx) ||
1075 nla_put_u32(vendor_event,
1076 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1077 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301078 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301079 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1080 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301081 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301082 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1083 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301084 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301085 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1086 pWifiIfaceStat->rssiAck))
1087 {
1088 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301089 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1090 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301091 return FALSE;
1092 }
1093
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301094#ifdef FEATURE_EXT_LL_STAT
1095 /*
1096 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1097 * then host should send Leaky AP stats to upper layer,
1098 * otherwise no need to send these stats.
1099 */
1100 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1101 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1102 )
1103 {
1104 hddLog(VOS_TRACE_LEVEL_INFO,
1105 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1106 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1107 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1108 pWifiIfaceStat->leakyApStat.rx_leak_window,
1109 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1110 if (nla_put_u32(vendor_event,
1111 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1112 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1113 nla_put_u32(vendor_event,
1114 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1115 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1116 nla_put_u32(vendor_event,
1117 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1118 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1119 nla_put_u64(vendor_event,
1120 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1121 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1122 {
1123 hddLog(VOS_TRACE_LEVEL_ERROR,
1124 FL("EXT_LL_STAT put fail"));
1125 vos_mem_free(pWifiIfaceStatTL);
1126 return FALSE;
1127 }
1128 }
1129#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301130 wmmInfo = nla_nest_start(vendor_event,
1131 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301132 if(!wmmInfo)
1133 {
1134 vos_mem_free(pWifiIfaceStatTL);
1135 return FALSE;
1136 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301137 for (i = 0; i < WIFI_AC_MAX; i++)
1138 {
1139 struct nlattr *wmmStats;
1140 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301141 if(!wmmStats)
1142 {
1143 vos_mem_free(pWifiIfaceStatTL);
1144 return FALSE;
1145 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301146 if (FALSE == put_wifi_wmm_ac_stat(
1147 &pWifiIfaceStat->AccessclassStats[i],
1148 vendor_event))
1149 {
1150 hddLog(VOS_TRACE_LEVEL_ERROR,
1151 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301152 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301153 return FALSE;
1154 }
1155
1156 nla_nest_end(vendor_event, wmmStats);
1157 }
1158 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301159 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301160 return TRUE;
1161}
1162
1163static tSirWifiInterfaceMode
1164 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1165{
1166 switch (deviceMode)
1167 {
1168 case WLAN_HDD_INFRA_STATION:
1169 return WIFI_INTERFACE_STA;
1170 case WLAN_HDD_SOFTAP:
1171 return WIFI_INTERFACE_SOFTAP;
1172 case WLAN_HDD_P2P_CLIENT:
1173 return WIFI_INTERFACE_P2P_CLIENT;
1174 case WLAN_HDD_P2P_GO:
1175 return WIFI_INTERFACE_P2P_GO;
1176 case WLAN_HDD_IBSS:
1177 return WIFI_INTERFACE_IBSS;
1178 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301179 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301180 }
1181}
1182
1183static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1184 tpSirWifiInterfaceInfo pInfo)
1185{
1186 v_U8_t *staMac = NULL;
1187 hdd_station_ctx_t *pHddStaCtx;
1188 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1189 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1190
1191 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1192
1193 vos_mem_copy(pInfo->macAddr,
1194 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1195
1196 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1197 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1198 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1199 {
1200 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1201 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1202 {
1203 pInfo->state = WIFI_DISCONNECTED;
1204 }
1205 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1206 {
1207 hddLog(VOS_TRACE_LEVEL_ERROR,
1208 "%s: Session ID %d, Connection is in progress", __func__,
1209 pAdapter->sessionId);
1210 pInfo->state = WIFI_ASSOCIATING;
1211 }
1212 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1213 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1214 {
1215 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1216 hddLog(VOS_TRACE_LEVEL_ERROR,
1217 "%s: client " MAC_ADDRESS_STR
1218 " is in the middle of WPS/EAPOL exchange.", __func__,
1219 MAC_ADDR_ARRAY(staMac));
1220 pInfo->state = WIFI_AUTHENTICATING;
1221 }
1222 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1223 {
1224 pInfo->state = WIFI_ASSOCIATED;
1225 vos_mem_copy(pInfo->bssid,
1226 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1227 vos_mem_copy(pInfo->ssid,
1228 pHddStaCtx->conn_info.SSID.SSID.ssId,
1229 pHddStaCtx->conn_info.SSID.SSID.length);
1230 //NULL Terminate the string.
1231 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1232 }
1233 }
1234 vos_mem_copy(pInfo->countryStr,
1235 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1236
1237 vos_mem_copy(pInfo->apCountryStr,
1238 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1239
1240 return TRUE;
1241}
1242
1243/*
1244 * hdd_link_layer_process_peer_stats () - This function is called after
1245 * receiving Link Layer Peer statistics from FW.This function converts
1246 * the firmware data to the NL data and sends the same to the kernel/upper
1247 * layers.
1248 */
1249static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1250 v_VOID_t *pData)
1251{
1252 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301253 tpSirWifiPeerStat pWifiPeerStat;
1254 tpSirWifiPeerInfo pWifiPeerInfo;
1255 struct nlattr *peerInfo;
1256 struct sk_buff *vendor_event;
1257 int status, i;
1258
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301259 ENTER();
1260
Sunil Duttc69bccb2014-05-26 21:30:20 +05301261 status = wlan_hdd_validate_context(pHddCtx);
1262 if (0 != status)
1263 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301264 return;
1265 }
1266
1267 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1268
1269 hddLog(VOS_TRACE_LEVEL_INFO,
1270 "LL_STATS_PEER_ALL : numPeers %u",
1271 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301272 /*
1273 * Allocate a size of 4096 for the peer stats comprising
1274 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1275 * sizeof (tSirWifiRateStat).Each field is put with an
1276 * NL attribute.The size of 4096 is considered assuming
1277 * that number of rates shall not exceed beyond 50 with
1278 * the sizeof (tSirWifiRateStat) being 32.
1279 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301280 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1281 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301282 if (!vendor_event)
1283 {
1284 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301285 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301286 __func__);
1287 return;
1288 }
1289 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301290 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1291 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1292 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301293 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1294 pWifiPeerStat->numPeers))
1295 {
1296 hddLog(VOS_TRACE_LEVEL_ERROR,
1297 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1298 kfree_skb(vendor_event);
1299 return;
1300 }
1301
1302 peerInfo = nla_nest_start(vendor_event,
1303 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301304 if(!peerInfo)
1305 {
1306 hddLog(VOS_TRACE_LEVEL_ERROR,
1307 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1308 __func__);
1309 kfree_skb(vendor_event);
1310 return;
1311 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301312
1313 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1314 pWifiPeerStat->peerInfo);
1315
1316 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1317 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301318 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301319 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301320
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301321 if(!peers)
1322 {
1323 hddLog(VOS_TRACE_LEVEL_ERROR,
1324 "%s: peer stats put fail",
1325 __func__);
1326 kfree_skb(vendor_event);
1327 return;
1328 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301329 if (FALSE == put_wifi_peer_info(
1330 pWifiPeerInfo, vendor_event))
1331 {
1332 hddLog(VOS_TRACE_LEVEL_ERROR,
1333 "%s: put_wifi_peer_info put fail", __func__);
1334 kfree_skb(vendor_event);
1335 return;
1336 }
1337
1338 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1339 pWifiPeerStat->peerInfo +
1340 (i * sizeof(tSirWifiPeerInfo)) +
1341 (numRate * sizeof (tSirWifiRateStat)));
1342 nla_nest_end(vendor_event, peers);
1343 }
1344 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301345 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301346 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301347}
1348
1349/*
1350 * hdd_link_layer_process_iface_stats () - This function is called after
1351 * receiving Link Layer Interface statistics from FW.This function converts
1352 * the firmware data to the NL data and sends the same to the kernel/upper
1353 * layers.
1354 */
1355static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1356 v_VOID_t *pData)
1357{
1358 tpSirWifiIfaceStat pWifiIfaceStat;
1359 struct sk_buff *vendor_event;
1360 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1361 int status;
1362
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301363 ENTER();
1364
Sunil Duttc69bccb2014-05-26 21:30:20 +05301365 status = wlan_hdd_validate_context(pHddCtx);
1366 if (0 != status)
1367 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301368 return;
1369 }
1370 /*
1371 * Allocate a size of 4096 for the interface stats comprising
1372 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1373 * assuming that all these fit with in the limit.Please take
1374 * a call on the limit based on the data requirements on
1375 * interface statistics.
1376 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301377 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1378 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301379 if (!vendor_event)
1380 {
1381 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301382 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301383 return;
1384 }
1385
1386 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1387
Dino Mycle3b9536d2014-07-09 22:05:24 +05301388
1389 if (FALSE == hdd_get_interface_info( pAdapter,
1390 &pWifiIfaceStat->info))
1391 {
1392 hddLog(VOS_TRACE_LEVEL_ERROR,
1393 FL("hdd_get_interface_info get fail") );
1394 kfree_skb(vendor_event);
1395 return;
1396 }
1397
1398 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1399 vendor_event))
1400 {
1401 hddLog(VOS_TRACE_LEVEL_ERROR,
1402 FL("put_wifi_iface_stats fail") );
1403 kfree_skb(vendor_event);
1404 return;
1405 }
1406
Sunil Duttc69bccb2014-05-26 21:30:20 +05301407 hddLog(VOS_TRACE_LEVEL_INFO,
1408 "WMI_LINK_STATS_IFACE Data");
1409
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301410 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301411
1412 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301413}
1414
1415/*
1416 * hdd_link_layer_process_radio_stats () - This function is called after
1417 * receiving Link Layer Radio statistics from FW.This function converts
1418 * the firmware data to the NL data and sends the same to the kernel/upper
1419 * layers.
1420 */
1421static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1422 v_VOID_t *pData)
1423{
1424 int status, i;
1425 tpSirWifiRadioStat pWifiRadioStat;
1426 tpSirWifiChannelStats pWifiChannelStats;
1427 struct sk_buff *vendor_event;
1428 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1429 struct nlattr *chList;
1430
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301431 ENTER();
1432
Sunil Duttc69bccb2014-05-26 21:30:20 +05301433 status = wlan_hdd_validate_context(pHddCtx);
1434 if (0 != status)
1435 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301436 return;
1437 }
1438 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1439
1440 hddLog(VOS_TRACE_LEVEL_INFO,
1441 "LL_STATS_RADIO"
1442 " radio is %d onTime is %u "
1443 " txTime is %u rxTime is %u "
1444 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301445 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301446 " onTimePnoScan is %u onTimeHs20 is %u "
1447 " numChannels is %u",
1448 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1449 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1450 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301451 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301452 pWifiRadioStat->onTimeRoamScan,
1453 pWifiRadioStat->onTimePnoScan,
1454 pWifiRadioStat->onTimeHs20,
1455 pWifiRadioStat->numChannels);
1456 /*
1457 * Allocate a size of 4096 for the Radio stats comprising
1458 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1459 * (tSirWifiChannelStats).Each channel data is put with an
1460 * NL attribute.The size of 4096 is considered assuming that
1461 * number of channels shall not exceed beyond 60 with the
1462 * sizeof (tSirWifiChannelStats) being 24 bytes.
1463 */
1464
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301465 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1466 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301467 if (!vendor_event)
1468 {
1469 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301470 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301471 return;
1472 }
1473
1474 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301475 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1476 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1477 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301478 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1479 pWifiRadioStat->radio) ||
1480 nla_put_u32(vendor_event,
1481 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1482 pWifiRadioStat->onTime) ||
1483 nla_put_u32(vendor_event,
1484 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1485 pWifiRadioStat->txTime) ||
1486 nla_put_u32(vendor_event,
1487 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1488 pWifiRadioStat->rxTime) ||
1489 nla_put_u32(vendor_event,
1490 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1491 pWifiRadioStat->onTimeScan) ||
1492 nla_put_u32(vendor_event,
1493 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1494 pWifiRadioStat->onTimeNbd) ||
1495 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301496 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1497 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301498 nla_put_u32(vendor_event,
1499 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1500 pWifiRadioStat->onTimeRoamScan) ||
1501 nla_put_u32(vendor_event,
1502 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1503 pWifiRadioStat->onTimePnoScan) ||
1504 nla_put_u32(vendor_event,
1505 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1506 pWifiRadioStat->onTimeHs20) ||
1507 nla_put_u32(vendor_event,
1508 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1509 pWifiRadioStat->numChannels))
1510 {
1511 hddLog(VOS_TRACE_LEVEL_ERROR,
1512 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1513 kfree_skb(vendor_event);
1514 return ;
1515 }
1516
1517 chList = nla_nest_start(vendor_event,
1518 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301519 if(!chList)
1520 {
1521 hddLog(VOS_TRACE_LEVEL_ERROR,
1522 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1523 __func__);
1524 kfree_skb(vendor_event);
1525 return;
1526 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301527 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1528 {
1529 struct nlattr *chInfo;
1530
1531 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1532 pWifiRadioStat->channels +
1533 (i * sizeof(tSirWifiChannelStats)));
1534
Sunil Duttc69bccb2014-05-26 21:30:20 +05301535 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301536 if(!chInfo)
1537 {
1538 hddLog(VOS_TRACE_LEVEL_ERROR,
1539 "%s: failed to put chInfo",
1540 __func__);
1541 kfree_skb(vendor_event);
1542 return;
1543 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301544
1545 if (nla_put_u32(vendor_event,
1546 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1547 pWifiChannelStats->channel.width) ||
1548 nla_put_u32(vendor_event,
1549 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1550 pWifiChannelStats->channel.centerFreq) ||
1551 nla_put_u32(vendor_event,
1552 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1553 pWifiChannelStats->channel.centerFreq0) ||
1554 nla_put_u32(vendor_event,
1555 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1556 pWifiChannelStats->channel.centerFreq1) ||
1557 nla_put_u32(vendor_event,
1558 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1559 pWifiChannelStats->onTime) ||
1560 nla_put_u32(vendor_event,
1561 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1562 pWifiChannelStats->ccaBusyTime))
1563 {
1564 hddLog(VOS_TRACE_LEVEL_ERROR,
1565 FL("cfg80211_vendor_event_alloc failed") );
1566 kfree_skb(vendor_event);
1567 return ;
1568 }
1569 nla_nest_end(vendor_event, chInfo);
1570 }
1571 nla_nest_end(vendor_event, chList);
1572
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301573 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301574
1575 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301576 return;
1577}
1578
1579/*
1580 * hdd_link_layer_stats_ind_callback () - This function is called after
1581 * receiving Link Layer indications from FW.This callback converts the firmware
1582 * data to the NL data and send the same to the kernel/upper layers.
1583 */
1584static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1585 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301586 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301587{
Dino Mycled3d50022014-07-07 12:58:25 +05301588 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1589 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301590 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301591 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301592 int status;
1593
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301594 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301595
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301596 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301597 if (0 != status)
1598 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301599 return;
1600 }
1601
Dino Mycled3d50022014-07-07 12:58:25 +05301602 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1603 if (NULL == pAdapter)
1604 {
1605 hddLog(VOS_TRACE_LEVEL_ERROR,
1606 FL(" MAC address %pM does not exist with host"),
1607 macAddr);
1608 return;
1609 }
1610
Sunil Duttc69bccb2014-05-26 21:30:20 +05301611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301612 "%s: Interface: %s LLStats indType: %d", __func__,
1613 pAdapter->dev->name, indType);
1614
Sunil Duttc69bccb2014-05-26 21:30:20 +05301615 switch (indType)
1616 {
1617 case SIR_HAL_LL_STATS_RESULTS_RSP:
1618 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301619 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301620 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1621 "respId = %u, moreResultToFollow = %u",
1622 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1623 macAddr, linkLayerStatsResults->respId,
1624 linkLayerStatsResults->moreResultToFollow);
1625
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301626 spin_lock(&hdd_context_lock);
1627 context = &pHddCtx->ll_stats_context;
1628 /* validate response received from target */
1629 if ((context->request_id != linkLayerStatsResults->respId) ||
1630 !(context->request_bitmap & linkLayerStatsResults->paramId))
1631 {
1632 spin_unlock(&hdd_context_lock);
1633 hddLog(LOGE,
1634 FL("Error : Request id %d response id %d request bitmap 0x%x"
1635 "response bitmap 0x%x"),
1636 context->request_id, linkLayerStatsResults->respId,
1637 context->request_bitmap, linkLayerStatsResults->paramId);
1638 return;
1639 }
1640 spin_unlock(&hdd_context_lock);
1641
Sunil Duttc69bccb2014-05-26 21:30:20 +05301642 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1643 {
1644 hdd_link_layer_process_radio_stats(pAdapter,
1645 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301646 spin_lock(&hdd_context_lock);
1647 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1648 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301649 }
1650 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1651 {
1652 hdd_link_layer_process_iface_stats(pAdapter,
1653 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301654 spin_lock(&hdd_context_lock);
1655 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1656 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301657 }
1658 else if ( linkLayerStatsResults->paramId &
1659 WMI_LINK_STATS_ALL_PEER )
1660 {
1661 hdd_link_layer_process_peer_stats(pAdapter,
1662 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301663 spin_lock(&hdd_context_lock);
1664 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1665 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301666 } /* WMI_LINK_STATS_ALL_PEER */
1667 else
1668 {
1669 hddLog(VOS_TRACE_LEVEL_ERROR,
1670 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1671 }
1672
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301673 spin_lock(&hdd_context_lock);
1674 /* complete response event if all requests are completed */
1675 if (0 == context->request_bitmap)
1676 complete(&context->response_event);
1677 spin_unlock(&hdd_context_lock);
1678
Sunil Duttc69bccb2014-05-26 21:30:20 +05301679 break;
1680 }
1681 default:
1682 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1683 break;
1684 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301685
1686 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301687 return;
1688}
1689
1690const struct
1691nla_policy
1692qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1693{
1694 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1695 { .type = NLA_U32 },
1696 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1697 { .type = NLA_U32 },
1698};
1699
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301700static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1701 struct wireless_dev *wdev,
1702 const void *data,
1703 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301704{
1705 int status;
1706 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301707 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301708 struct net_device *dev = wdev->netdev;
1709 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1710 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1711
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301712 ENTER();
1713
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714 status = wlan_hdd_validate_context(pHddCtx);
1715 if (0 != status)
1716 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301717 return -EINVAL;
1718 }
1719
1720 if (NULL == pAdapter)
1721 {
1722 hddLog(VOS_TRACE_LEVEL_ERROR,
1723 FL("HDD adapter is Null"));
1724 return -ENODEV;
1725 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301726 /* check the LLStats Capability */
1727 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1728 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1729 {
1730 hddLog(VOS_TRACE_LEVEL_ERROR,
1731 FL("Link Layer Statistics not supported by Firmware"));
1732 return -EINVAL;
1733 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301734
1735 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1736 (struct nlattr *)data,
1737 data_len, qca_wlan_vendor_ll_set_policy))
1738 {
1739 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1740 return -EINVAL;
1741 }
1742 if (!tb_vendor
1743 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1744 {
1745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1746 return -EINVAL;
1747 }
1748 if (!tb_vendor[
1749 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1750 {
1751 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1752 return -EINVAL;
1753 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301754 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301755 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301756
Dino Mycledf0a5d92014-07-04 09:41:55 +05301757 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301758 nla_get_u32(
1759 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1760
Dino Mycledf0a5d92014-07-04 09:41:55 +05301761 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301762 nla_get_u32(
1763 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1764
Dino Mycled3d50022014-07-07 12:58:25 +05301765 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1766 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301767
1768
1769 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301770 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1771 "Statistics Gathering = %d ",
1772 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1773 linkLayerStatsSetReq.mpduSizeThreshold,
1774 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301775
1776 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1777 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301778 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301779 {
1780 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1781 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301782 return -EINVAL;
1783
1784 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301785
Sunil Duttc69bccb2014-05-26 21:30:20 +05301786 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301787 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301788 {
1789 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1790 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301791 return -EINVAL;
1792 }
1793
1794 pAdapter->isLinkLayerStatsSet = 1;
1795
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301796 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301797 return 0;
1798}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301799static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1800 struct wireless_dev *wdev,
1801 const void *data,
1802 int data_len)
1803{
1804 int ret = 0;
1805
1806 vos_ssr_protect(__func__);
1807 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1808 vos_ssr_unprotect(__func__);
1809
1810 return ret;
1811}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301812
1813const struct
1814nla_policy
1815qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1816{
1817 /* Unsigned 32bit value provided by the caller issuing the GET stats
1818 * command. When reporting
1819 * the stats results, the driver uses the same value to indicate
1820 * which GET request the results
1821 * correspond to.
1822 */
1823 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1824
1825 /* Unsigned 32bit value . bit mask to identify what statistics are
1826 requested for retrieval */
1827 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1828};
1829
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301830static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1831 struct wireless_dev *wdev,
1832 const void *data,
1833 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301834{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301835 unsigned long rc;
1836 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301837 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1838 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301839 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301840 struct net_device *dev = wdev->netdev;
1841 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301842 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301843 int status;
1844
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301845 ENTER();
1846
Sunil Duttc69bccb2014-05-26 21:30:20 +05301847 status = wlan_hdd_validate_context(pHddCtx);
1848 if (0 != status)
1849 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301850 return -EINVAL ;
1851 }
1852
1853 if (NULL == pAdapter)
1854 {
1855 hddLog(VOS_TRACE_LEVEL_FATAL,
1856 "%s: HDD adapter is Null", __func__);
1857 return -ENODEV;
1858 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301859
1860 if (pHddStaCtx == NULL)
1861 {
1862 hddLog(VOS_TRACE_LEVEL_FATAL,
1863 "%s: HddStaCtx is Null", __func__);
1864 return -ENODEV;
1865 }
1866
Dino Mycledf0a5d92014-07-04 09:41:55 +05301867 /* check the LLStats Capability */
1868 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1869 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1870 {
1871 hddLog(VOS_TRACE_LEVEL_ERROR,
1872 FL("Link Layer Statistics not supported by Firmware"));
1873 return -EINVAL;
1874 }
1875
Sunil Duttc69bccb2014-05-26 21:30:20 +05301876
1877 if (!pAdapter->isLinkLayerStatsSet)
1878 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05301879 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301880 "%s: isLinkLayerStatsSet : %d",
1881 __func__, pAdapter->isLinkLayerStatsSet);
1882 return -EINVAL;
1883 }
1884
Mukul Sharma10313ba2015-07-29 19:14:39 +05301885 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1886 {
1887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1888 "%s: Roaming in progress, so unable to proceed this request", __func__);
1889 return -EBUSY;
1890 }
1891
Sunil Duttc69bccb2014-05-26 21:30:20 +05301892 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1893 (struct nlattr *)data,
1894 data_len, qca_wlan_vendor_ll_get_policy))
1895 {
1896 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1897 return -EINVAL;
1898 }
1899
1900 if (!tb_vendor
1901 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1902 {
1903 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1904 return -EINVAL;
1905 }
1906
1907 if (!tb_vendor
1908 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1909 {
1910 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1911 return -EINVAL;
1912 }
1913
Sunil Duttc69bccb2014-05-26 21:30:20 +05301914
Dino Mycledf0a5d92014-07-04 09:41:55 +05301915 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 nla_get_u32( tb_vendor[
1917 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301918 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919 nla_get_u32( tb_vendor[
1920 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1921
Dino Mycled3d50022014-07-07 12:58:25 +05301922 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1923 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301924
1925 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301926 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1927 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301928 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301929
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301930 spin_lock(&hdd_context_lock);
1931 context = &pHddCtx->ll_stats_context;
1932 context->request_id = linkLayerStatsGetReq.reqId;
1933 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1934 INIT_COMPLETION(context->response_event);
1935 spin_unlock(&hdd_context_lock);
1936
Sunil Duttc69bccb2014-05-26 21:30:20 +05301937 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301938 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301939 {
1940 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1941 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301942 return -EINVAL;
1943 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301944
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301945 rc = wait_for_completion_timeout(&context->response_event,
1946 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1947 if (!rc)
1948 {
1949 hddLog(LOGE,
1950 FL("Target response timed out request id %d request bitmap 0x%x"),
1951 context->request_id, context->request_bitmap);
1952 return -ETIMEDOUT;
1953 }
1954
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301955 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301956 return 0;
1957}
1958
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301959static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1960 struct wireless_dev *wdev,
1961 const void *data,
1962 int data_len)
1963{
1964 int ret = 0;
1965
1966 vos_ssr_protect(__func__);
1967 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1968 vos_ssr_unprotect(__func__);
1969
1970 return ret;
1971}
1972
Sunil Duttc69bccb2014-05-26 21:30:20 +05301973const struct
1974nla_policy
1975qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1976{
1977 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1978 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1979 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1980 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1981};
1982
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301983static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1984 struct wireless_dev *wdev,
1985 const void *data,
1986 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301987{
1988 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1989 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301990 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301991 struct net_device *dev = wdev->netdev;
1992 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1993 u32 statsClearReqMask;
1994 u8 stopReq;
1995 int status;
1996
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301997 ENTER();
1998
Sunil Duttc69bccb2014-05-26 21:30:20 +05301999 status = wlan_hdd_validate_context(pHddCtx);
2000 if (0 != status)
2001 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302002 return -EINVAL;
2003 }
2004
2005 if (NULL == pAdapter)
2006 {
2007 hddLog(VOS_TRACE_LEVEL_FATAL,
2008 "%s: HDD adapter is Null", __func__);
2009 return -ENODEV;
2010 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302011 /* check the LLStats Capability */
2012 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2013 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2014 {
2015 hddLog(VOS_TRACE_LEVEL_ERROR,
2016 FL("Enable LLStats Capability"));
2017 return -EINVAL;
2018 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302019
2020 if (!pAdapter->isLinkLayerStatsSet)
2021 {
2022 hddLog(VOS_TRACE_LEVEL_FATAL,
2023 "%s: isLinkLayerStatsSet : %d",
2024 __func__, pAdapter->isLinkLayerStatsSet);
2025 return -EINVAL;
2026 }
2027
2028 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2029 (struct nlattr *)data,
2030 data_len, qca_wlan_vendor_ll_clr_policy))
2031 {
2032 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2033 return -EINVAL;
2034 }
2035
2036 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2037
2038 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2039 {
2040 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2041 return -EINVAL;
2042
2043 }
2044
Sunil Duttc69bccb2014-05-26 21:30:20 +05302045
Dino Mycledf0a5d92014-07-04 09:41:55 +05302046 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302047 nla_get_u32(
2048 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2049
Dino Mycledf0a5d92014-07-04 09:41:55 +05302050 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302051 nla_get_u8(
2052 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2053
2054 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302055 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302056
Dino Mycled3d50022014-07-07 12:58:25 +05302057 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2058 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302059
2060 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302061 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2062 "statsClearReqMask = 0x%X, stopReq = %d",
2063 linkLayerStatsClearReq.reqId,
2064 linkLayerStatsClearReq.macAddr,
2065 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302066 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302067
2068 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302069 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302070 {
2071 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302072 hdd_station_ctx_t *pHddStaCtx;
2073
2074 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2075 if (VOS_STATUS_SUCCESS !=
2076 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2077 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2078 {
2079 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2080 "WLANTL_ClearInterfaceStats Failed", __func__);
2081 return -EINVAL;
2082 }
2083 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2084 (statsClearReqMask & WIFI_STATS_IFACE)) {
2085 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2086 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2087 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2088 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2089 }
2090
Sunil Duttc69bccb2014-05-26 21:30:20 +05302091 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2092 2 * sizeof(u32) +
2093 NLMSG_HDRLEN);
2094
2095 if (temp_skbuff != NULL)
2096 {
2097
2098 if (nla_put_u32(temp_skbuff,
2099 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2100 statsClearReqMask) ||
2101 nla_put_u32(temp_skbuff,
2102 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2103 stopReq))
2104 {
2105 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2106 kfree_skb(temp_skbuff);
2107 return -EINVAL;
2108 }
2109 /* If the ask is to stop the stats collection as part of clear
2110 * (stopReq = 1) , ensure that no further requests of get
2111 * go to the firmware by having isLinkLayerStatsSet set to 0.
2112 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302113 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302114 * case the firmware is just asked to clear the statistics.
2115 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302116 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302117 pAdapter->isLinkLayerStatsSet = 0;
2118 return cfg80211_vendor_cmd_reply(temp_skbuff);
2119 }
2120 return -ENOMEM;
2121 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302122
2123 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302124 return -EINVAL;
2125}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302126static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2127 struct wireless_dev *wdev,
2128 const void *data,
2129 int data_len)
2130{
2131 int ret = 0;
2132
2133 vos_ssr_protect(__func__);
2134 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2135 vos_ssr_unprotect(__func__);
2136
2137 return ret;
2138
2139
2140}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2142
Dino Mycle6fb96c12014-06-10 11:52:40 +05302143#ifdef WLAN_FEATURE_EXTSCAN
2144static const struct nla_policy
2145wlan_hdd_extscan_config_policy
2146 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2147{
2148 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2149 { .type = NLA_U32 },
2150 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2151 { .type = NLA_U32 },
2152 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2153 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2154 { .type = NLA_U32 },
2155 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2157
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2159 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2161 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2162 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302163 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2164 { .type = NLA_U32 },
2165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2166 { .type = NLA_U32 },
2167 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2168 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2170 { .type = NLA_U32 },
2171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2172 { .type = NLA_U32 },
2173 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2174 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2176 { .type = NLA_U8 },
2177 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302178 { .type = NLA_U8 },
2179 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2180 { .type = NLA_U8 },
2181 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2182 { .type = NLA_U8 },
2183
2184 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2185 { .type = NLA_U32 },
2186 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2187 { .type = NLA_UNSPEC },
2188 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2189 { .type = NLA_S32 },
2190 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2191 { .type = NLA_S32 },
2192 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2193 { .type = NLA_U32 },
2194 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2195 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302196 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2197 { .type = NLA_U32 },
2198 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2199 { .type = NLA_BINARY,
2200 .len = IEEE80211_MAX_SSID_LEN + 1 },
2201 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302202 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302203 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2204 { .type = NLA_U32 },
2205 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2206 { .type = NLA_U8 },
2207 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2208 { .type = NLA_S32 },
2209 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2210 { .type = NLA_S32 },
2211 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2212 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302213};
2214
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302215/**
2216 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2217 * @ctx: hdd global context
2218 * @data: capabilities data
2219 *
2220 * Return: none
2221 */
2222static void
2223wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302224{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302225 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302226 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302227 tSirEXTScanCapabilitiesEvent *data =
2228 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302229
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302230 ENTER();
2231
2232 if (wlan_hdd_validate_context(pHddCtx))
2233 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302234 return;
2235 }
2236
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302237 if (!pMsg)
2238 {
2239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2240 return;
2241 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302242
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302243 vos_spin_lock_acquire(&hdd_context_lock);
2244
2245 context = &pHddCtx->ext_scan_context;
2246 /* validate response received from target*/
2247 if (context->request_id != data->requestId)
2248 {
2249 vos_spin_lock_release(&hdd_context_lock);
2250 hddLog(LOGE,
2251 FL("Target response id did not match: request_id %d resposne_id %d"),
2252 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302253 return;
2254 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302255 else
2256 {
2257 context->capability_response = *data;
2258 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302259 }
2260
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302261 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302262
Dino Mycle6fb96c12014-06-10 11:52:40 +05302263 return;
2264}
2265
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302266/*
2267 * define short names for the global vendor params
2268 * used by wlan_hdd_send_ext_scan_capability()
2269 */
2270#define PARAM_REQUEST_ID \
2271 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2272#define PARAM_STATUS \
2273 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2274#define MAX_SCAN_CACHE_SIZE \
2275 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2276#define MAX_SCAN_BUCKETS \
2277 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2278#define MAX_AP_CACHE_PER_SCAN \
2279 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2280#define MAX_RSSI_SAMPLE_SIZE \
2281 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2282#define MAX_SCAN_RPT_THRHOLD \
2283 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2284#define MAX_HOTLIST_BSSIDS \
2285 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2286#define MAX_BSSID_HISTORY_ENTRIES \
2287 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2288#define MAX_HOTLIST_SSIDS \
2289 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302290#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2291 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302292
2293static int wlan_hdd_send_ext_scan_capability(void *ctx)
2294{
2295 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2296 struct sk_buff *skb = NULL;
2297 int ret;
2298 tSirEXTScanCapabilitiesEvent *data;
2299 tANI_U32 nl_buf_len;
2300
2301 ret = wlan_hdd_validate_context(pHddCtx);
2302 if (0 != ret)
2303 {
2304 return ret;
2305 }
2306
2307 data = &(pHddCtx->ext_scan_context.capability_response);
2308
2309 nl_buf_len = NLMSG_HDRLEN;
2310 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2311 (sizeof(data->status) + NLA_HDRLEN) +
2312 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2313 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2314 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2315 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2316 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2317 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2318 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2319 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2320
2321 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2322
2323 if (!skb)
2324 {
2325 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2326 return -ENOMEM;
2327 }
2328
2329 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2330 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2331 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2332 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2333 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2334 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2335 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2336 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2337
2338 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2339 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2340 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2341 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2342 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2343 data->maxApPerScan) ||
2344 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2345 data->maxRssiSampleSize) ||
2346 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2347 data->maxScanReportingThreshold) ||
2348 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2349 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2350 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302351 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2352 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302353 {
2354 hddLog(LOGE, FL("nla put fail"));
2355 goto nla_put_failure;
2356 }
2357
2358 cfg80211_vendor_cmd_reply(skb);
2359 return 0;
2360
2361nla_put_failure:
2362 kfree_skb(skb);
2363 return -EINVAL;;
2364}
2365
2366/*
2367 * done with short names for the global vendor params
2368 * used by wlan_hdd_send_ext_scan_capability()
2369 */
2370#undef PARAM_REQUEST_ID
2371#undef PARAM_STATUS
2372#undef MAX_SCAN_CACHE_SIZE
2373#undef MAX_SCAN_BUCKETS
2374#undef MAX_AP_CACHE_PER_SCAN
2375#undef MAX_RSSI_SAMPLE_SIZE
2376#undef MAX_SCAN_RPT_THRHOLD
2377#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302378#undef MAX_BSSID_HISTORY_ENTRIES
2379#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302380
2381static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2382{
2383 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2384 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302385 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302386 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302387
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302388 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302389
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302390 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302391 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302392
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302393 if (!pMsg)
2394 {
2395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302396 return;
2397 }
2398
Dino Mycle6fb96c12014-06-10 11:52:40 +05302399 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2400 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2401
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302402 context = &pHddCtx->ext_scan_context;
2403 spin_lock(&hdd_context_lock);
2404 if (context->request_id == pData->requestId) {
2405 context->response_status = pData->status ? -EINVAL : 0;
2406 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302407 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302408 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302409
2410 /*
2411 * Store the Request ID for comparing with the requestID obtained
2412 * in other requests.HDD shall return a failure is the extscan_stop
2413 * request is issued with a different requestId as that of the
2414 * extscan_start request. Also, This requestId shall be used while
2415 * indicating the full scan results to the upper layers.
2416 * The requestId is stored with the assumption that the firmware
2417 * shall return the ext scan start request's requestId in ext scan
2418 * start response.
2419 */
2420 if (pData->status == 0)
2421 pMac->sme.extScanStartReqId = pData->requestId;
2422
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302423 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302424 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302425}
2426
2427
2428static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2429{
2430 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2431 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302432 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302433
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302434 ENTER();
2435
2436 if (wlan_hdd_validate_context(pHddCtx)){
2437 return;
2438 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302439
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302440 if (!pMsg)
2441 {
2442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302443 return;
2444 }
2445
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302446 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2447 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302448
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302449 context = &pHddCtx->ext_scan_context;
2450 spin_lock(&hdd_context_lock);
2451 if (context->request_id == pData->requestId) {
2452 context->response_status = pData->status ? -EINVAL : 0;
2453 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302454 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302455 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302456
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302457 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302458 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302459}
2460
Dino Mycle6fb96c12014-06-10 11:52:40 +05302461static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2462 void *pMsg)
2463{
2464 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302465 tpSirEXTScanSetBssidHotListRspParams pData =
2466 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302467 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302468
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302469 ENTER();
2470
2471 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302472 return;
2473 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302474
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302475 if (!pMsg)
2476 {
2477 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2478 return;
2479 }
2480
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302481 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2482 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302483
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302484 context = &pHddCtx->ext_scan_context;
2485 spin_lock(&hdd_context_lock);
2486 if (context->request_id == pData->requestId) {
2487 context->response_status = pData->status ? -EINVAL : 0;
2488 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302489 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302490 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302491
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302492 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302493 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302494}
2495
2496static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2497 void *pMsg)
2498{
2499 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302500 tpSirEXTScanResetBssidHotlistRspParams pData =
2501 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302502 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302503
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302504 ENTER();
2505
2506 if (wlan_hdd_validate_context(pHddCtx)) {
2507 return;
2508 }
2509 if (!pMsg)
2510 {
2511 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302512 return;
2513 }
2514
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302515 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2516 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302517
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302518 context = &pHddCtx->ext_scan_context;
2519 spin_lock(&hdd_context_lock);
2520 if (context->request_id == pData->requestId) {
2521 context->response_status = pData->status ? -EINVAL : 0;
2522 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302523 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302524 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302525
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302526 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302527 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302528}
2529
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302530static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2531 void *pMsg)
2532{
2533 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2534 tpSirEXTScanSetSsidHotListRspParams pData =
2535 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2536 struct hdd_ext_scan_context *context;
2537
2538 if (wlan_hdd_validate_context(pHddCtx)){
2539 return;
2540 }
2541
2542 if (!pMsg)
2543 {
2544 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2545 return;
2546 }
2547
2548 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2549 pData->status);
2550
2551 context = &pHddCtx->ext_scan_context;
2552 spin_lock(&hdd_context_lock);
2553 if (context->request_id == pData->requestId) {
2554 context->response_status = pData->status ? -EINVAL : 0;
2555 complete(&context->response_event);
2556 }
2557 spin_unlock(&hdd_context_lock);
2558
2559 return;
2560}
2561
2562static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2563 void *pMsg)
2564{
2565 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2566 tpSirEXTScanResetSsidHotlistRspParams pData =
2567 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2568 struct hdd_ext_scan_context *context;
2569
2570 if (wlan_hdd_validate_context(pHddCtx)) {
2571 return;
2572 }
2573 if (!pMsg)
2574 {
2575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2576 return;
2577 }
2578
2579 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2580 pData->status);
2581
2582 context = &pHddCtx->ext_scan_context;
2583 spin_lock(&hdd_context_lock);
2584 if (context->request_id == pData->requestId) {
2585 context->response_status = pData->status ? -EINVAL : 0;
2586 complete(&context->response_event);
2587 }
2588 spin_unlock(&hdd_context_lock);
2589
2590 return;
2591}
2592
2593
Dino Mycle6fb96c12014-06-10 11:52:40 +05302594static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2595 void *pMsg)
2596{
2597 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2598 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302599 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302600 tANI_S32 totalResults;
2601 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302602 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2603 struct hdd_ext_scan_context *context;
2604 bool ignore_cached_results = false;
2605 tExtscanCachedScanResult *result;
2606 struct nlattr *nla_results;
2607 tANI_U16 ieLength= 0;
2608 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302609
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302610 ENTER();
2611
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302612 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302613 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302614
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302615 if (!pMsg)
2616 {
2617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2618 return;
2619 }
2620
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302621 spin_lock(&hdd_context_lock);
2622 context = &pHddCtx->ext_scan_context;
2623 ignore_cached_results = context->ignore_cached_results;
2624 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302626 if (ignore_cached_results) {
2627 hddLog(LOGE,
2628 FL("Ignore the cached results received after timeout"));
2629 return;
2630 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302631
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302632 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2633 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302634
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302635 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302636
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302637 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2638 scan_id_index++) {
2639 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302640
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302641 totalResults = result->num_results;
2642 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2643 result->scan_id, result->flags, totalResults);
2644 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302645
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302646 do{
2647 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2648 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2649 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302650
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302651 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2652 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2653
2654 if (!skb) {
2655 hddLog(VOS_TRACE_LEVEL_ERROR,
2656 FL("cfg80211_vendor_event_alloc failed"));
2657 return;
2658 }
2659
2660 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2661
2662 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2663 pData->requestId) ||
2664 nla_put_u32(skb,
2665 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2666 resultsPerEvent)) {
2667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2668 goto fail;
2669 }
2670 if (nla_put_u8(skb,
2671 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2672 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302673 {
2674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2675 goto fail;
2676 }
2677
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302678 if (nla_put_u32(skb,
2679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2680 result->scan_id)) {
2681 hddLog(LOGE, FL("put fail"));
2682 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302683 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302684
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302685 nla_results = nla_nest_start(skb,
2686 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2687 if (!nla_results)
2688 goto fail;
2689
2690 if (resultsPerEvent) {
2691 struct nlattr *aps;
2692 struct nlattr *nla_result;
2693
2694 nla_result = nla_nest_start(skb, scan_id_index);
2695 if(!nla_result)
2696 goto fail;
2697
2698 if (nla_put_u32(skb,
2699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2700 result->scan_id) ||
2701 nla_put_u32(skb,
2702 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2703 result->flags) ||
2704 nla_put_u32(skb,
2705 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2706 totalResults)) {
2707 hddLog(LOGE, FL("put fail"));
2708 goto fail;
2709 }
2710
2711 aps = nla_nest_start(skb,
2712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2713 if (!aps)
2714 {
2715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2716 goto fail;
2717 }
2718
2719 head_ptr = (tpSirWifiScanResult) &(result->ap);
2720
2721 for (j = 0; j < resultsPerEvent; j++, i++) {
2722 struct nlattr *ap;
2723 pSirWifiScanResult = head_ptr + i;
2724
2725 /*
2726 * Firmware returns timestamp from WiFi turn ON till
2727 * BSSID was cached (in seconds). Add this with
2728 * time gap between system boot up to WiFi turn ON
2729 * to derive the time since boot when the
2730 * BSSID was cached.
2731 */
2732 pSirWifiScanResult->ts += pHddCtx->wifi_turn_on_time_since_boot;
2733 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2734 "Ssid (%s)"
2735 "Bssid: %pM "
2736 "Channel (%u)"
2737 "Rssi (%d)"
2738 "RTT (%u)"
2739 "RTT_SD (%u)"
2740 "Beacon Period %u"
2741 "Capability 0x%x "
2742 "Ie length %d",
2743 i,
2744 pSirWifiScanResult->ts,
2745 pSirWifiScanResult->ssid,
2746 pSirWifiScanResult->bssid,
2747 pSirWifiScanResult->channel,
2748 pSirWifiScanResult->rssi,
2749 pSirWifiScanResult->rtt,
2750 pSirWifiScanResult->rtt_sd,
2751 pSirWifiScanResult->beaconPeriod,
2752 pSirWifiScanResult->capability,
2753 ieLength);
2754
2755 ap = nla_nest_start(skb, j + 1);
2756 if (!ap)
2757 {
2758 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2759 goto fail;
2760 }
2761
2762 if (nla_put_u64(skb,
2763 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2764 pSirWifiScanResult->ts) )
2765 {
2766 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2767 goto fail;
2768 }
2769 if (nla_put(skb,
2770 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2771 sizeof(pSirWifiScanResult->ssid),
2772 pSirWifiScanResult->ssid) )
2773 {
2774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2775 goto fail;
2776 }
2777 if (nla_put(skb,
2778 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2779 sizeof(pSirWifiScanResult->bssid),
2780 pSirWifiScanResult->bssid) )
2781 {
2782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2783 goto fail;
2784 }
2785 if (nla_put_u32(skb,
2786 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2787 pSirWifiScanResult->channel) )
2788 {
2789 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2790 goto fail;
2791 }
2792 if (nla_put_s32(skb,
2793 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2794 pSirWifiScanResult->rssi) )
2795 {
2796 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2797 goto fail;
2798 }
2799 if (nla_put_u32(skb,
2800 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2801 pSirWifiScanResult->rtt) )
2802 {
2803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2804 goto fail;
2805 }
2806 if (nla_put_u32(skb,
2807 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2808 pSirWifiScanResult->rtt_sd))
2809 {
2810 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2811 goto fail;
2812 }
2813 if (nla_put_u32(skb,
2814 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2815 pSirWifiScanResult->beaconPeriod))
2816 {
2817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2818 goto fail;
2819 }
2820 if (nla_put_u32(skb,
2821 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2822 pSirWifiScanResult->capability))
2823 {
2824 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2825 goto fail;
2826 }
2827 if (nla_put_u32(skb,
2828 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2829 ieLength))
2830 {
2831 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2832 goto fail;
2833 }
2834
2835 if (ieLength)
2836 if (nla_put(skb,
2837 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2838 ieLength, ie)) {
2839 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2840 goto fail;
2841 }
2842
2843 nla_nest_end(skb, ap);
2844 }
2845 nla_nest_end(skb, aps);
2846 nla_nest_end(skb, nla_result);
2847 }
2848
2849 nla_nest_end(skb, nla_results);
2850
2851 cfg80211_vendor_cmd_reply(skb);
2852
2853 } while (totalResults > 0);
2854 }
2855
2856 if (!pData->moreData) {
2857 spin_lock(&hdd_context_lock);
2858 context->response_status = 0;
2859 complete(&context->response_event);
2860 spin_unlock(&hdd_context_lock);
2861 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302862
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302863 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302864 return;
2865fail:
2866 kfree_skb(skb);
2867 return;
2868}
2869
2870static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2871 void *pMsg)
2872{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302873 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302874 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2875 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302876 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302877
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302878 ENTER();
2879
2880 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302881 hddLog(LOGE,
2882 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302883 return;
2884 }
2885 if (!pMsg)
2886 {
2887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302888 return;
2889 }
2890
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302891 if (pData->bss_found)
2892 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2893 else
2894 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2895
Dino Mycle6fb96c12014-06-10 11:52:40 +05302896 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302897#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2898 NULL,
2899#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302900 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302901 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302902
2903 if (!skb) {
2904 hddLog(VOS_TRACE_LEVEL_ERROR,
2905 FL("cfg80211_vendor_event_alloc failed"));
2906 return;
2907 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302908
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302909 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2910 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2911 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2912 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2913
2914 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302915 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2916 "Ssid (%s) "
2917 "Bssid (" MAC_ADDRESS_STR ") "
2918 "Channel (%u) "
2919 "Rssi (%d) "
2920 "RTT (%u) "
2921 "RTT_SD (%u) ",
2922 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302923 pData->bssHotlist[i].ts,
2924 pData->bssHotlist[i].ssid,
2925 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2926 pData->bssHotlist[i].channel,
2927 pData->bssHotlist[i].rssi,
2928 pData->bssHotlist[i].rtt,
2929 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302930 }
2931
2932 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2933 pData->requestId) ||
2934 nla_put_u32(skb,
2935 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302936 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302937 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2938 goto fail;
2939 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302940 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302941 struct nlattr *aps;
2942
2943 aps = nla_nest_start(skb,
2944 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2945 if (!aps)
2946 goto fail;
2947
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302948 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302949 struct nlattr *ap;
2950
2951 ap = nla_nest_start(skb, i + 1);
2952 if (!ap)
2953 goto fail;
2954
2955 if (nla_put_u64(skb,
2956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302957 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302958 nla_put(skb,
2959 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302960 sizeof(pData->bssHotlist[i].ssid),
2961 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302962 nla_put(skb,
2963 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302964 sizeof(pData->bssHotlist[i].bssid),
2965 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302966 nla_put_u32(skb,
2967 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302968 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302969 nla_put_s32(skb,
2970 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302971 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302972 nla_put_u32(skb,
2973 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302974 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302975 nla_put_u32(skb,
2976 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302977 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302978 goto fail;
2979
2980 nla_nest_end(skb, ap);
2981 }
2982 nla_nest_end(skb, aps);
2983
2984 if (nla_put_u8(skb,
2985 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2986 pData->moreData))
2987 goto fail;
2988 }
2989
2990 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302991 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302992 return;
2993
2994fail:
2995 kfree_skb(skb);
2996 return;
2997
2998}
Dino Mycle6fb96c12014-06-10 11:52:40 +05302999
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303000/**
3001 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
3002 * Handle an SSID hotlist match event
3003 * @ctx: HDD context registered with SME
3004 * @event: The SSID hotlist match event
3005 *
3006 * This function will take an SSID match event that was generated by
3007 * firmware and will convert it into a cfg80211 vendor event which is
3008 * sent to userspace.
3009 *
3010 * Return: none
3011 */
3012static void
3013wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
3014 void *pMsg)
3015{
3016 hdd_context_t *hdd_ctx = ctx;
3017 struct sk_buff *skb;
3018 tANI_U32 i, index;
3019 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3020
3021 ENTER();
3022
3023 if (wlan_hdd_validate_context(hdd_ctx)) {
3024 hddLog(LOGE,
3025 FL("HDD context is not valid or response"));
3026 return;
3027 }
3028 if (!pMsg)
3029 {
3030 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3031 return;
3032 }
3033
3034 if (pData->ssid_found) {
3035 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3036 hddLog(LOG1, "SSID hotlist found");
3037 } else {
3038 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3039 hddLog(LOG1, "SSID hotlist lost");
3040 }
3041
3042 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3043#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3044 NULL,
3045#endif
3046 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3047 index, GFP_KERNEL);
3048
3049 if (!skb) {
3050 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3051 return;
3052 }
3053 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3054 pData->requestId, pData->numHotlistSsid, pData->moreData);
3055
3056 for (i = 0; i < pData->numHotlistSsid; i++) {
3057 hddLog(LOG1, "[i=%d] Timestamp %llu "
3058 "Ssid: %s "
3059 "Bssid (" MAC_ADDRESS_STR ") "
3060 "Channel %u "
3061 "Rssi %d "
3062 "RTT %u "
3063 "RTT_SD %u",
3064 i,
3065 pData->ssidHotlist[i].ts,
3066 pData->ssidHotlist[i].ssid,
3067 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3068 pData->ssidHotlist[i].channel,
3069 pData->ssidHotlist[i].rssi,
3070 pData->ssidHotlist[i].rtt,
3071 pData->ssidHotlist[i].rtt_sd);
3072 }
3073
3074 if (nla_put_u32(skb,
3075 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3076 pData->requestId) ||
3077 nla_put_u32(skb,
3078 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3079 pData->numHotlistSsid)) {
3080 hddLog(LOGE, FL("put fail"));
3081 goto fail;
3082 }
3083
3084 if (pData->numHotlistSsid) {
3085 struct nlattr *aps;
3086 aps = nla_nest_start(skb,
3087 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3088 if (!aps) {
3089 hddLog(LOGE, FL("nest fail"));
3090 goto fail;
3091 }
3092
3093 for (i = 0; i < pData->numHotlistSsid; i++) {
3094 struct nlattr *ap;
3095
3096 ap = nla_nest_start(skb, i);
3097 if (!ap) {
3098 hddLog(LOGE, FL("nest fail"));
3099 goto fail;
3100 }
3101
3102 if (nla_put_u64(skb,
3103 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3104 pData->ssidHotlist[i].ts) ||
3105 nla_put(skb,
3106 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3107 sizeof(pData->ssidHotlist[i].ssid),
3108 pData->ssidHotlist[i].ssid) ||
3109 nla_put(skb,
3110 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3111 sizeof(pData->ssidHotlist[i].bssid),
3112 pData->ssidHotlist[i].bssid) ||
3113 nla_put_u32(skb,
3114 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3115 pData->ssidHotlist[i].channel) ||
3116 nla_put_s32(skb,
3117 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3118 pData->ssidHotlist[i].rssi) ||
3119 nla_put_u32(skb,
3120 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3121 pData->ssidHotlist[i].rtt) ||
3122 nla_put_u32(skb,
3123 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3124 pData->ssidHotlist[i].rtt_sd)) {
3125 hddLog(LOGE, FL("put fail"));
3126 goto fail;
3127 }
3128 nla_nest_end(skb, ap);
3129 }
3130 nla_nest_end(skb, aps);
3131
3132 if (nla_put_u8(skb,
3133 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3134 pData->moreData)) {
3135 hddLog(LOGE, FL("put fail"));
3136 goto fail;
3137 }
3138 }
3139
3140 cfg80211_vendor_event(skb, GFP_KERNEL);
3141 return;
3142
3143fail:
3144 kfree_skb(skb);
3145 return;
3146
3147}
3148
3149
Dino Mycle6fb96c12014-06-10 11:52:40 +05303150static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3151 void *pMsg)
3152{
3153 struct sk_buff *skb;
3154 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3155 tpSirWifiFullScanResultEvent pData =
3156 (tpSirWifiFullScanResultEvent) (pMsg);
3157
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303158 ENTER();
3159
3160 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303161 hddLog(LOGE,
3162 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303163 return;
3164 }
3165 if (!pMsg)
3166 {
3167 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303168 return;
3169 }
3170
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303171 /*
3172 * If the full scan result including IE data exceeds NL 4K size
3173 * limitation, drop that beacon/probe rsp frame.
3174 */
3175 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3176 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3177 return;
3178 }
3179
Dino Mycle6fb96c12014-06-10 11:52:40 +05303180 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303181#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3182 NULL,
3183#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303184 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3185 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3186 GFP_KERNEL);
3187
3188 if (!skb) {
3189 hddLog(VOS_TRACE_LEVEL_ERROR,
3190 FL("cfg80211_vendor_event_alloc failed"));
3191 return;
3192 }
3193
Dino Mycle6fb96c12014-06-10 11:52:40 +05303194 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3195 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3196 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3197 "Ssid (%s)"
3198 "Bssid (" MAC_ADDRESS_STR ")"
3199 "Channel (%u)"
3200 "Rssi (%d)"
3201 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303202 "RTT_SD (%u)"
3203 "Bcn Period %d"
3204 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303205 pData->ap.ts,
3206 pData->ap.ssid,
3207 MAC_ADDR_ARRAY(pData->ap.bssid),
3208 pData->ap.channel,
3209 pData->ap.rssi,
3210 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303211 pData->ap.rtt_sd,
3212 pData->ap.beaconPeriod,
3213 pData->ap.capability);
3214
Dino Mycle6fb96c12014-06-10 11:52:40 +05303215 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3216 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3217 pData->requestId) ||
3218 nla_put_u64(skb,
3219 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3220 pData->ap.ts) ||
3221 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3222 sizeof(pData->ap.ssid),
3223 pData->ap.ssid) ||
3224 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3225 WNI_CFG_BSSID_LEN,
3226 pData->ap.bssid) ||
3227 nla_put_u32(skb,
3228 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3229 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303230 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303231 pData->ap.rssi) ||
3232 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3233 pData->ap.rtt) ||
3234 nla_put_u32(skb,
3235 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3236 pData->ap.rtt_sd) ||
3237 nla_put_u16(skb,
3238 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3239 pData->ap.beaconPeriod) ||
3240 nla_put_u16(skb,
3241 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3242 pData->ap.capability) ||
3243 nla_put_u32(skb,
3244 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303245 pData->ieLength) ||
3246 nla_put_u8(skb,
3247 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3248 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303249 {
3250 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3251 goto nla_put_failure;
3252 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303253
3254 if (pData->ieLength) {
3255 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3256 pData->ieLength,
3257 pData->ie))
3258 {
3259 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3260 goto nla_put_failure;
3261 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303262 }
3263
3264 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303265 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303266 return;
3267
3268nla_put_failure:
3269 kfree_skb(skb);
3270 return;
3271}
3272
3273static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3274 void *pMsg)
3275{
3276 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3277 struct sk_buff *skb = NULL;
3278 tpSirEXTScanResultsAvailableIndParams pData =
3279 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3280
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303281 ENTER();
3282
3283 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303284 hddLog(LOGE,
3285 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303286 return;
3287 }
3288 if (!pMsg)
3289 {
3290 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303291 return;
3292 }
3293
3294 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303295#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3296 NULL,
3297#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303298 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3299 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3300 GFP_KERNEL);
3301
3302 if (!skb) {
3303 hddLog(VOS_TRACE_LEVEL_ERROR,
3304 FL("cfg80211_vendor_event_alloc failed"));
3305 return;
3306 }
3307
Dino Mycle6fb96c12014-06-10 11:52:40 +05303308 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3309 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3310 pData->numResultsAvailable);
3311 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3312 pData->requestId) ||
3313 nla_put_u32(skb,
3314 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3315 pData->numResultsAvailable)) {
3316 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3317 goto nla_put_failure;
3318 }
3319
3320 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303321 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303322 return;
3323
3324nla_put_failure:
3325 kfree_skb(skb);
3326 return;
3327}
3328
3329static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3330{
3331 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3332 struct sk_buff *skb = NULL;
3333 tpSirEXTScanProgressIndParams pData =
3334 (tpSirEXTScanProgressIndParams) pMsg;
3335
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303336 ENTER();
3337
3338 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303339 hddLog(LOGE,
3340 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303341 return;
3342 }
3343 if (!pMsg)
3344 {
3345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303346 return;
3347 }
3348
3349 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303350#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3351 NULL,
3352#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303353 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3354 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3355 GFP_KERNEL);
3356
3357 if (!skb) {
3358 hddLog(VOS_TRACE_LEVEL_ERROR,
3359 FL("cfg80211_vendor_event_alloc failed"));
3360 return;
3361 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303362 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303363 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3364 pData->extScanEventType);
3365 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3366 pData->status);
3367
3368 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3369 pData->extScanEventType) ||
3370 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303371 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3372 pData->requestId) ||
3373 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303374 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3375 pData->status)) {
3376 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3377 goto nla_put_failure;
3378 }
3379
3380 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303381 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303382 return;
3383
3384nla_put_failure:
3385 kfree_skb(skb);
3386 return;
3387}
3388
3389void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3390 void *pMsg)
3391{
3392 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3393
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303394 ENTER();
3395
Dino Mycle6fb96c12014-06-10 11:52:40 +05303396 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303397 return;
3398 }
3399
3400 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3401
3402
3403 switch(evType) {
3404 case SIR_HAL_EXTSCAN_START_RSP:
3405 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3406 break;
3407
3408 case SIR_HAL_EXTSCAN_STOP_RSP:
3409 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3410 break;
3411 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3412 /* There is no need to send this response to upper layer
3413 Just log the message */
3414 hddLog(VOS_TRACE_LEVEL_INFO,
3415 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3416 break;
3417 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3418 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3419 break;
3420
3421 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3422 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3423 break;
3424
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303425 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3426 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3427 break;
3428
3429 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3430 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3431 break;
3432
Dino Mycle6fb96c12014-06-10 11:52:40 +05303433 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303434 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303435 break;
3436 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3437 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3438 break;
3439 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3440 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3441 break;
3442 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3443 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3444 break;
3445 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3446 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3447 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303448 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3449 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3450 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303451 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3452 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3453 break;
3454 default:
3455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3456 break;
3457 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303458 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303459}
3460
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303461static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3462 struct wireless_dev *wdev,
3463 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303464{
Dino Myclee8843b32014-07-04 14:21:45 +05303465 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303466 struct net_device *dev = wdev->netdev;
3467 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3468 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3469 struct nlattr
3470 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3471 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303472 struct hdd_ext_scan_context *context;
3473 unsigned long rc;
3474 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303475
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303476 ENTER();
3477
Dino Mycle6fb96c12014-06-10 11:52:40 +05303478 status = wlan_hdd_validate_context(pHddCtx);
3479 if (0 != status)
3480 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303481 return -EINVAL;
3482 }
Dino Myclee8843b32014-07-04 14:21:45 +05303483 /* check the EXTScan Capability */
3484 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303485 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3486 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303487 {
3488 hddLog(VOS_TRACE_LEVEL_ERROR,
3489 FL("EXTScan not enabled/supported by Firmware"));
3490 return -EINVAL;
3491 }
3492
Dino Mycle6fb96c12014-06-10 11:52:40 +05303493 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3494 data, dataLen,
3495 wlan_hdd_extscan_config_policy)) {
3496 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3497 return -EINVAL;
3498 }
3499
3500 /* Parse and fetch request Id */
3501 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3502 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3503 return -EINVAL;
3504 }
3505
Dino Myclee8843b32014-07-04 14:21:45 +05303506 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303507 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303508 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303509
Dino Myclee8843b32014-07-04 14:21:45 +05303510 reqMsg.sessionId = pAdapter->sessionId;
3511 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303512
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303513 vos_spin_lock_acquire(&hdd_context_lock);
3514 context = &pHddCtx->ext_scan_context;
3515 context->request_id = reqMsg.requestId;
3516 INIT_COMPLETION(context->response_event);
3517 vos_spin_lock_release(&hdd_context_lock);
3518
Dino Myclee8843b32014-07-04 14:21:45 +05303519 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303520 if (!HAL_STATUS_SUCCESS(status)) {
3521 hddLog(VOS_TRACE_LEVEL_ERROR,
3522 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303523 return -EINVAL;
3524 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303525
3526 rc = wait_for_completion_timeout(&context->response_event,
3527 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3528 if (!rc) {
3529 hddLog(LOGE, FL("Target response timed out"));
3530 return -ETIMEDOUT;
3531 }
3532
3533 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3534 if (ret)
3535 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3536
3537 return ret;
3538
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303539 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303540 return 0;
3541}
3542
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303543static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3544 struct wireless_dev *wdev,
3545 const void *data, int dataLen)
3546{
3547 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303548
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303549 vos_ssr_protect(__func__);
3550 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3551 vos_ssr_unprotect(__func__);
3552
3553 return ret;
3554}
3555
3556static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3557 struct wireless_dev *wdev,
3558 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303559{
Dino Myclee8843b32014-07-04 14:21:45 +05303560 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303561 struct net_device *dev = wdev->netdev;
3562 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3563 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3564 struct nlattr
3565 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3566 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303567 struct hdd_ext_scan_context *context;
3568 unsigned long rc;
3569 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303570
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303571 ENTER();
3572
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303573 if (VOS_FTM_MODE == hdd_get_conparam()) {
3574 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3575 return -EINVAL;
3576 }
3577
Dino Mycle6fb96c12014-06-10 11:52:40 +05303578 status = wlan_hdd_validate_context(pHddCtx);
3579 if (0 != status)
3580 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581 return -EINVAL;
3582 }
Dino Myclee8843b32014-07-04 14:21:45 +05303583 /* check the EXTScan Capability */
3584 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303585 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3586 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303587 {
3588 hddLog(VOS_TRACE_LEVEL_ERROR,
3589 FL("EXTScan not enabled/supported by Firmware"));
3590 return -EINVAL;
3591 }
3592
Dino Mycle6fb96c12014-06-10 11:52:40 +05303593 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3594 data, dataLen,
3595 wlan_hdd_extscan_config_policy)) {
3596 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3597 return -EINVAL;
3598 }
3599 /* Parse and fetch request Id */
3600 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3602 return -EINVAL;
3603 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303604
Dino Myclee8843b32014-07-04 14:21:45 +05303605 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303606 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3607
Dino Myclee8843b32014-07-04 14:21:45 +05303608 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303609
Dino Myclee8843b32014-07-04 14:21:45 +05303610 reqMsg.sessionId = pAdapter->sessionId;
3611 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303612
3613 /* Parse and fetch flush parameter */
3614 if (!tb
3615 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3616 {
3617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3618 goto failed;
3619 }
Dino Myclee8843b32014-07-04 14:21:45 +05303620 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303621 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3622
Dino Myclee8843b32014-07-04 14:21:45 +05303623 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303624
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303625 spin_lock(&hdd_context_lock);
3626 context = &pHddCtx->ext_scan_context;
3627 context->request_id = reqMsg.requestId;
3628 context->ignore_cached_results = false;
3629 INIT_COMPLETION(context->response_event);
3630 spin_unlock(&hdd_context_lock);
3631
Dino Myclee8843b32014-07-04 14:21:45 +05303632 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303633 if (!HAL_STATUS_SUCCESS(status)) {
3634 hddLog(VOS_TRACE_LEVEL_ERROR,
3635 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303636 return -EINVAL;
3637 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303638
3639 rc = wait_for_completion_timeout(&context->response_event,
3640 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3641 if (!rc) {
3642 hddLog(LOGE, FL("Target response timed out"));
3643 retval = -ETIMEDOUT;
3644 spin_lock(&hdd_context_lock);
3645 context->ignore_cached_results = true;
3646 spin_unlock(&hdd_context_lock);
3647 } else {
3648 spin_lock(&hdd_context_lock);
3649 retval = context->response_status;
3650 spin_unlock(&hdd_context_lock);
3651 }
3652
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303653 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303654 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303655
3656failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303657 return -EINVAL;
3658}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303659static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3660 struct wireless_dev *wdev,
3661 const void *data, int dataLen)
3662{
3663 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303664
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303665 vos_ssr_protect(__func__);
3666 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3667 vos_ssr_unprotect(__func__);
3668
3669 return ret;
3670}
3671
3672static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303673 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303674 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303675{
3676 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3677 struct net_device *dev = wdev->netdev;
3678 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3679 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3680 struct nlattr
3681 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3682 struct nlattr
3683 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3684 struct nlattr *apTh;
3685 eHalStatus status;
3686 tANI_U8 i = 0;
3687 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303688 struct hdd_ext_scan_context *context;
3689 tANI_U32 request_id;
3690 unsigned long rc;
3691 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303693 ENTER();
3694
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303695 if (VOS_FTM_MODE == hdd_get_conparam()) {
3696 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3697 return -EINVAL;
3698 }
3699
Dino Mycle6fb96c12014-06-10 11:52:40 +05303700 status = wlan_hdd_validate_context(pHddCtx);
3701 if (0 != status)
3702 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303703 return -EINVAL;
3704 }
Dino Myclee8843b32014-07-04 14:21:45 +05303705 /* check the EXTScan Capability */
3706 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303707 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3708 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303709 {
3710 hddLog(VOS_TRACE_LEVEL_ERROR,
3711 FL("EXTScan not enabled/supported by Firmware"));
3712 return -EINVAL;
3713 }
3714
Dino Mycle6fb96c12014-06-10 11:52:40 +05303715 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3716 data, dataLen,
3717 wlan_hdd_extscan_config_policy)) {
3718 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3719 return -EINVAL;
3720 }
3721
3722 /* Parse and fetch request Id */
3723 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3724 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3725 return -EINVAL;
3726 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303727 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3728 vos_mem_malloc(sizeof(*pReqMsg));
3729 if (!pReqMsg) {
3730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3731 return -ENOMEM;
3732 }
3733
Dino Myclee8843b32014-07-04 14:21:45 +05303734
Dino Mycle6fb96c12014-06-10 11:52:40 +05303735 pReqMsg->requestId = nla_get_u32(
3736 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3737 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3738
3739 /* Parse and fetch number of APs */
3740 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3742 goto fail;
3743 }
3744
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303745 /* Parse and fetch lost ap sample size */
3746 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3747 hddLog(LOGE, FL("attr lost ap sample size failed"));
3748 goto fail;
3749 }
3750
3751 pReqMsg->lostBssidSampleSize = nla_get_u32(
3752 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3753 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3754
Dino Mycle6fb96c12014-06-10 11:52:40 +05303755 pReqMsg->sessionId = pAdapter->sessionId;
3756 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3757
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303758 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303759 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303760 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303761
3762 nla_for_each_nested(apTh,
3763 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3764 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3765 nla_data(apTh), nla_len(apTh),
3766 NULL)) {
3767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3768 goto fail;
3769 }
3770
3771 /* Parse and fetch MAC address */
3772 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3773 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3774 goto fail;
3775 }
3776 memcpy(pReqMsg->ap[i].bssid, nla_data(
3777 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3778 sizeof(tSirMacAddr));
3779 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3780
3781 /* Parse and fetch low RSSI */
3782 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3784 goto fail;
3785 }
3786 pReqMsg->ap[i].low = nla_get_s32(
3787 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3788 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3789
3790 /* Parse and fetch high RSSI */
3791 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3793 goto fail;
3794 }
3795 pReqMsg->ap[i].high = nla_get_s32(
3796 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3797 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3798 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303799 i++;
3800 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303801
3802 context = &pHddCtx->ext_scan_context;
3803 spin_lock(&hdd_context_lock);
3804 INIT_COMPLETION(context->response_event);
3805 context->request_id = request_id = pReqMsg->requestId;
3806 spin_unlock(&hdd_context_lock);
3807
Dino Mycle6fb96c12014-06-10 11:52:40 +05303808 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3809 if (!HAL_STATUS_SUCCESS(status)) {
3810 hddLog(VOS_TRACE_LEVEL_ERROR,
3811 FL("sme_SetBssHotlist failed(err=%d)"), status);
3812 vos_mem_free(pReqMsg);
3813 return -EINVAL;
3814 }
3815
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303816 /* request was sent -- wait for the response */
3817 rc = wait_for_completion_timeout(&context->response_event,
3818 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3819
3820 if (!rc) {
3821 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3822 retval = -ETIMEDOUT;
3823 } else {
3824 spin_lock(&hdd_context_lock);
3825 if (context->request_id == request_id)
3826 retval = context->response_status;
3827 else
3828 retval = -EINVAL;
3829 spin_unlock(&hdd_context_lock);
3830 }
3831
Dino Myclee8843b32014-07-04 14:21:45 +05303832 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303833 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303834 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303835
3836fail:
3837 vos_mem_free(pReqMsg);
3838 return -EINVAL;
3839}
3840
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303841static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3842 struct wireless_dev *wdev,
3843 const void *data, int dataLen)
3844{
3845 int ret = 0;
3846
3847 vos_ssr_protect(__func__);
3848 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3849 dataLen);
3850 vos_ssr_unprotect(__func__);
3851
3852 return ret;
3853}
3854
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303855/*
3856 * define short names for the global vendor params
3857 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3858 */
3859#define PARAM_MAX \
3860QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3861#define PARAM_REQUEST_ID \
3862QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3863#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3864QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3865#define PARAMS_NUM_SSID \
3866QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3867#define THRESHOLD_PARAM \
3868QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3869#define PARAM_SSID \
3870QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3871#define PARAM_BAND \
3872QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3873#define PARAM_RSSI_LOW \
3874QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3875#define PARAM_RSSI_HIGH \
3876QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3877
3878/**
3879 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3880 * @wiphy: Pointer to wireless phy
3881 * @wdev: Pointer to wireless device
3882 * @data: Pointer to data
3883 * @data_len: Data length
3884 *
3885 * Return: 0 on success, negative errno on failure
3886 */
3887static int
3888__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3889 struct wireless_dev *wdev,
3890 const void *data,
3891 int data_len)
3892{
3893 tSirEXTScanSetSsidHotListReqParams *request;
3894 struct net_device *dev = wdev->netdev;
3895 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3896 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3897 struct nlattr *tb[PARAM_MAX + 1];
3898 struct nlattr *tb2[PARAM_MAX + 1];
3899 struct nlattr *ssids;
3900 struct hdd_ext_scan_context *context;
3901 uint32_t request_id;
3902 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3903 int ssid_len;
3904 eHalStatus status;
3905 int i, rem, retval;
3906 unsigned long rc;
3907
3908 ENTER();
3909
3910 if (VOS_FTM_MODE == hdd_get_conparam()) {
3911 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3912 return -EINVAL;
3913 }
3914
3915 retval = wlan_hdd_validate_context(hdd_ctx);
3916 if (0 != retval) {
3917 hddLog(LOGE, FL("HDD context is not valid"));
3918 return -EINVAL;
3919 }
3920
3921 /* check the EXTScan Capability */
3922 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303923 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3924 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303925 {
3926 hddLog(VOS_TRACE_LEVEL_ERROR,
3927 FL("EXTScan not enabled/supported by Firmware"));
3928 return -EINVAL;
3929 }
3930
3931 if (nla_parse(tb, PARAM_MAX,
3932 data, data_len,
3933 wlan_hdd_extscan_config_policy)) {
3934 hddLog(LOGE, FL("Invalid ATTR"));
3935 return -EINVAL;
3936 }
3937
3938 request = vos_mem_malloc(sizeof(*request));
3939 if (!request) {
3940 hddLog(LOGE, FL("vos_mem_malloc failed"));
3941 return -ENOMEM;
3942 }
3943
3944 /* Parse and fetch request Id */
3945 if (!tb[PARAM_REQUEST_ID]) {
3946 hddLog(LOGE, FL("attr request id failed"));
3947 goto fail;
3948 }
3949
3950 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3951 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3952
3953 /* Parse and fetch lost SSID sample size */
3954 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3955 hddLog(LOGE, FL("attr number of Ssid failed"));
3956 goto fail;
3957 }
3958 request->lost_ssid_sample_size =
3959 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3960 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3961 request->lost_ssid_sample_size);
3962
3963 /* Parse and fetch number of hotlist SSID */
3964 if (!tb[PARAMS_NUM_SSID]) {
3965 hddLog(LOGE, FL("attr number of Ssid failed"));
3966 goto fail;
3967 }
3968 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3969 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3970
3971 request->session_id = adapter->sessionId;
3972 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3973
3974 i = 0;
3975 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3976 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3977 hddLog(LOGE,
3978 FL("Too Many SSIDs, %d exceeds %d"),
3979 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3980 break;
3981 }
3982 if (nla_parse(tb2, PARAM_MAX,
3983 nla_data(ssids), nla_len(ssids),
3984 wlan_hdd_extscan_config_policy)) {
3985 hddLog(LOGE, FL("nla_parse failed"));
3986 goto fail;
3987 }
3988
3989 /* Parse and fetch SSID */
3990 if (!tb2[PARAM_SSID]) {
3991 hddLog(LOGE, FL("attr ssid failed"));
3992 goto fail;
3993 }
3994 nla_memcpy(ssid_string,
3995 tb2[PARAM_SSID],
3996 sizeof(ssid_string));
3997 hddLog(LOG1, FL("SSID %s"),
3998 ssid_string);
3999 ssid_len = strlen(ssid_string);
4000 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
4001 request->ssid[i].ssid.length = ssid_len;
4002 request->ssid[i].ssid.ssId[ssid_len] = '\0';
4003 hddLog(LOG1, FL("After copying SSID %s"),
4004 request->ssid[i].ssid.ssId);
4005 hddLog(LOG1, FL("After copying length: %d"),
4006 ssid_len);
4007
4008 /* Parse and fetch low RSSI */
4009 if (!tb2[PARAM_BAND]) {
4010 hddLog(LOGE, FL("attr band failed"));
4011 goto fail;
4012 }
4013 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
4014 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
4015
4016 /* Parse and fetch low RSSI */
4017 if (!tb2[PARAM_RSSI_LOW]) {
4018 hddLog(LOGE, FL("attr low RSSI failed"));
4019 goto fail;
4020 }
4021 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4022 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4023
4024 /* Parse and fetch high RSSI */
4025 if (!tb2[PARAM_RSSI_HIGH]) {
4026 hddLog(LOGE, FL("attr high RSSI failed"));
4027 goto fail;
4028 }
4029 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4030 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4031 i++;
4032 }
4033
4034 context = &hdd_ctx->ext_scan_context;
4035 spin_lock(&hdd_context_lock);
4036 INIT_COMPLETION(context->response_event);
4037 context->request_id = request_id = request->request_id;
4038 spin_unlock(&hdd_context_lock);
4039
4040 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4041 if (!HAL_STATUS_SUCCESS(status)) {
4042 hddLog(LOGE,
4043 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4044 goto fail;
4045 }
4046
4047 vos_mem_free(request);
4048
4049 /* request was sent -- wait for the response */
4050 rc = wait_for_completion_timeout(&context->response_event,
4051 msecs_to_jiffies
4052 (WLAN_WAIT_TIME_EXTSCAN));
4053 if (!rc) {
4054 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4055 retval = -ETIMEDOUT;
4056 } else {
4057 spin_lock(&hdd_context_lock);
4058 if (context->request_id == request_id)
4059 retval = context->response_status;
4060 else
4061 retval = -EINVAL;
4062 spin_unlock(&hdd_context_lock);
4063 }
4064
4065 return retval;
4066
4067fail:
4068 vos_mem_free(request);
4069 return -EINVAL;
4070}
4071
4072/*
4073 * done with short names for the global vendor params
4074 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4075 */
4076#undef PARAM_MAX
4077#undef PARAM_REQUEST_ID
4078#undef PARAMS_NUM_SSID
4079#undef THRESHOLD_PARAM
4080#undef PARAM_SSID
4081#undef PARAM_BAND
4082#undef PARAM_RSSI_LOW
4083#undef PARAM_RSSI_HIGH
4084
4085static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4086 struct wireless_dev *wdev,
4087 const void *data, int dataLen)
4088{
4089 int ret = 0;
4090
4091 vos_ssr_protect(__func__);
4092 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4093 dataLen);
4094 vos_ssr_unprotect(__func__);
4095
4096 return ret;
4097}
4098
4099static int
4100__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4101 struct wireless_dev *wdev,
4102 const void *data,
4103 int data_len)
4104{
4105 tSirEXTScanResetSsidHotlistReqParams request;
4106 struct net_device *dev = wdev->netdev;
4107 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4108 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4109 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4110 struct hdd_ext_scan_context *context;
4111 uint32_t request_id;
4112 eHalStatus status;
4113 int retval;
4114 unsigned long rc;
4115
4116 ENTER();
4117
4118 if (VOS_FTM_MODE == hdd_get_conparam()) {
4119 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4120 return -EINVAL;
4121 }
4122
4123 retval = wlan_hdd_validate_context(hdd_ctx);
4124 if (0 != retval) {
4125 hddLog(LOGE, FL("HDD context is not valid"));
4126 return -EINVAL;
4127 }
4128
4129 /* check the EXTScan Capability */
4130 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304131 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4132 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304133 {
4134 hddLog(LOGE,
4135 FL("EXTScan not enabled/supported by Firmware"));
4136 return -EINVAL;
4137 }
4138
4139 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4140 data, data_len,
4141 wlan_hdd_extscan_config_policy)) {
4142 hddLog(LOGE, FL("Invalid ATTR"));
4143 return -EINVAL;
4144 }
4145
4146 /* Parse and fetch request Id */
4147 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4148 hddLog(LOGE, FL("attr request id failed"));
4149 return -EINVAL;
4150 }
4151
4152 request.requestId = nla_get_u32(
4153 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4154 request.sessionId = adapter->sessionId;
4155 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4156 request.sessionId);
4157
4158 context = &hdd_ctx->ext_scan_context;
4159 spin_lock(&hdd_context_lock);
4160 INIT_COMPLETION(context->response_event);
4161 context->request_id = request_id = request.requestId;
4162 spin_unlock(&hdd_context_lock);
4163
4164 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4165 if (!HAL_STATUS_SUCCESS(status)) {
4166 hddLog(LOGE,
4167 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4168 return -EINVAL;
4169 }
4170
4171 /* request was sent -- wait for the response */
4172 rc = wait_for_completion_timeout(&context->response_event,
4173 msecs_to_jiffies
4174 (WLAN_WAIT_TIME_EXTSCAN));
4175 if (!rc) {
4176 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4177 retval = -ETIMEDOUT;
4178 } else {
4179 spin_lock(&hdd_context_lock);
4180 if (context->request_id == request_id)
4181 retval = context->response_status;
4182 else
4183 retval = -EINVAL;
4184 spin_unlock(&hdd_context_lock);
4185 }
4186
4187 return retval;
4188}
4189
4190static int
4191wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4192 struct wireless_dev *wdev,
4193 const void *data,
4194 int data_len)
4195{
4196 int ret;
4197
4198 vos_ssr_protect(__func__);
4199 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4200 data, data_len);
4201 vos_ssr_unprotect(__func__);
4202
4203 return ret;
4204}
4205
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304206static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304207 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304208 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304209{
4210 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4211 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4212 tANI_U8 numChannels = 0;
4213 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304214 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304215 tWifiBand wifiBand;
4216 eHalStatus status;
4217 struct sk_buff *replySkb;
4218 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304219 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304220
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304221 ENTER();
4222
Dino Mycle6fb96c12014-06-10 11:52:40 +05304223 status = wlan_hdd_validate_context(pHddCtx);
4224 if (0 != status)
4225 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304226 return -EINVAL;
4227 }
Dino Myclee8843b32014-07-04 14:21:45 +05304228
Dino Mycle6fb96c12014-06-10 11:52:40 +05304229 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4230 data, dataLen,
4231 wlan_hdd_extscan_config_policy)) {
4232 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4233 return -EINVAL;
4234 }
4235
4236 /* Parse and fetch request Id */
4237 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4239 return -EINVAL;
4240 }
4241 requestId = nla_get_u32(
4242 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4243 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4244
4245 /* Parse and fetch wifi band */
4246 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4247 {
4248 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4249 return -EINVAL;
4250 }
4251 wifiBand = nla_get_u32(
4252 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4253 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4254
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304255 /* Parse and fetch max channels */
4256 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4257 {
4258 hddLog(LOGE, FL("attr max channels failed"));
4259 return -EINVAL;
4260 }
4261 maxChannels = nla_get_u32(
4262 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4263 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4264
Dino Mycle6fb96c12014-06-10 11:52:40 +05304265 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4266 wifiBand, ChannelList,
4267 &numChannels);
4268 if (eHAL_STATUS_SUCCESS != status) {
4269 hddLog(VOS_TRACE_LEVEL_ERROR,
4270 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4271 return -EINVAL;
4272 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304273
4274 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304275 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304276
Dino Mycle6fb96c12014-06-10 11:52:40 +05304277 for (i = 0; i < numChannels; i++)
4278 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4279
4280 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4281 sizeof(u32) * numChannels +
4282 NLMSG_HDRLEN);
4283
4284 if (!replySkb) {
4285 hddLog(VOS_TRACE_LEVEL_ERROR,
4286 FL("valid channels: buffer alloc fail"));
4287 return -EINVAL;
4288 }
4289 if (nla_put_u32(replySkb,
4290 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4291 numChannels) ||
4292 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4293 sizeof(u32) * numChannels, ChannelList)) {
4294
4295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4296 kfree_skb(replySkb);
4297 return -EINVAL;
4298 }
4299
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304300 ret = cfg80211_vendor_cmd_reply(replySkb);
4301
4302 EXIT();
4303 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304304}
4305
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304306static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4307 struct wireless_dev *wdev,
4308 const void *data, int dataLen)
4309{
4310 int ret = 0;
4311
4312 vos_ssr_protect(__func__);
4313 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4314 dataLen);
4315 vos_ssr_unprotect(__func__);
4316
4317 return ret;
4318}
4319
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304320static int hdd_extscan_start_fill_bucket_channel_spec(
4321 hdd_context_t *pHddCtx,
4322 tpSirEXTScanStartReqParams pReqMsg,
4323 struct nlattr **tb)
4324{
4325 struct nlattr *bucket[
4326 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4327 struct nlattr *channel[
4328 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4329 struct nlattr *buckets;
4330 struct nlattr *channels;
4331 int rem1, rem2;
4332 eHalStatus status;
4333 tANI_U8 bktIndex, j, numChannels;
4334 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4335 tANI_U32 passive_max_chn_time, active_max_chn_time;
4336
4337 bktIndex = 0;
4338
4339 nla_for_each_nested(buckets,
4340 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4341 if (nla_parse(bucket,
4342 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4343 nla_data(buckets), nla_len(buckets), NULL)) {
4344 hddLog(LOGE, FL("nla_parse failed"));
4345 return -EINVAL;
4346 }
4347
4348 /* Parse and fetch bucket spec */
4349 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4350 hddLog(LOGE, FL("attr bucket index failed"));
4351 return -EINVAL;
4352 }
4353 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4354 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4355 hddLog(LOG1, FL("Bucket spec Index %d"),
4356 pReqMsg->buckets[bktIndex].bucket);
4357
4358 /* Parse and fetch wifi band */
4359 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4360 hddLog(LOGE, FL("attr wifi band failed"));
4361 return -EINVAL;
4362 }
4363 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4364 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4365 hddLog(LOG1, FL("Wifi band %d"),
4366 pReqMsg->buckets[bktIndex].band);
4367
4368 /* Parse and fetch period */
4369 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4370 hddLog(LOGE, FL("attr period failed"));
4371 return -EINVAL;
4372 }
4373 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4374 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4375 hddLog(LOG1, FL("period %d"),
4376 pReqMsg->buckets[bktIndex].period);
4377
4378 /* Parse and fetch report events */
4379 if (!bucket[
4380 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4381 hddLog(LOGE, FL("attr report events failed"));
4382 return -EINVAL;
4383 }
4384 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4385 bucket[
4386 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4387 hddLog(LOG1, FL("report events %d"),
4388 pReqMsg->buckets[bktIndex].reportEvents);
4389
4390 /* Parse and fetch max period */
4391 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4392 hddLog(LOGE, FL("attr max period failed"));
4393 return -EINVAL;
4394 }
4395 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4396 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4397 hddLog(LOG1, FL("max period %u"),
4398 pReqMsg->buckets[bktIndex].max_period);
4399
4400 /* Parse and fetch exponent */
4401 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4402 hddLog(LOGE, FL("attr exponent failed"));
4403 return -EINVAL;
4404 }
4405 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4406 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4407 hddLog(LOG1, FL("exponent %u"),
4408 pReqMsg->buckets[bktIndex].exponent);
4409
4410 /* Parse and fetch step count */
4411 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4412 hddLog(LOGE, FL("attr step count failed"));
4413 return -EINVAL;
4414 }
4415 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4416 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4417 hddLog(LOG1, FL("Step count %u"),
4418 pReqMsg->buckets[bktIndex].step_count);
4419
4420 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4421 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4422
4423 /* Framework shall pass the channel list if the input WiFi band is
4424 * WIFI_BAND_UNSPECIFIED.
4425 * If the input WiFi band is specified (any value other than
4426 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4427 */
4428 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4429 numChannels = 0;
4430 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4431 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4432 pReqMsg->buckets[bktIndex].band,
4433 chanList, &numChannels);
4434 if (!HAL_STATUS_SUCCESS(status)) {
4435 hddLog(LOGE,
4436 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4437 status);
4438 return -EINVAL;
4439 }
4440
4441 pReqMsg->buckets[bktIndex].numChannels =
4442 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4443 hddLog(LOG1, FL("Num channels %d"),
4444 pReqMsg->buckets[bktIndex].numChannels);
4445
4446 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4447 j++) {
4448 pReqMsg->buckets[bktIndex].channels[j].channel =
4449 chanList[j];
4450 pReqMsg->buckets[bktIndex].channels[j].
4451 chnlClass = 0;
4452 if (CSR_IS_CHANNEL_DFS(
4453 vos_freq_to_chan(chanList[j]))) {
4454 pReqMsg->buckets[bktIndex].channels[j].
4455 passive = 1;
4456 pReqMsg->buckets[bktIndex].channels[j].
4457 dwellTimeMs = passive_max_chn_time;
4458 } else {
4459 pReqMsg->buckets[bktIndex].channels[j].
4460 passive = 0;
4461 pReqMsg->buckets[bktIndex].channels[j].
4462 dwellTimeMs = active_max_chn_time;
4463 }
4464
4465 hddLog(LOG1,
4466 "Channel %u Passive %u Dwell time %u ms",
4467 pReqMsg->buckets[bktIndex].channels[j].channel,
4468 pReqMsg->buckets[bktIndex].channels[j].passive,
4469 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4470 }
4471
4472 bktIndex++;
4473 continue;
4474 }
4475
4476 /* Parse and fetch number of channels */
4477 if (!bucket[
4478 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4479 hddLog(LOGE, FL("attr num channels failed"));
4480 return -EINVAL;
4481 }
4482
4483 pReqMsg->buckets[bktIndex].numChannels =
4484 nla_get_u32(bucket[
4485 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4486 hddLog(LOG1, FL("num channels %d"),
4487 pReqMsg->buckets[bktIndex].numChannels);
4488
4489 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4490 hddLog(LOGE, FL("attr channel spec failed"));
4491 return -EINVAL;
4492 }
4493
4494 j = 0;
4495 nla_for_each_nested(channels,
4496 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4497 if (nla_parse(channel,
4498 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4499 nla_data(channels), nla_len(channels),
4500 wlan_hdd_extscan_config_policy)) {
4501 hddLog(LOGE, FL("nla_parse failed"));
4502 return -EINVAL;
4503 }
4504
4505 /* Parse and fetch channel */
4506 if (!channel[
4507 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4508 hddLog(LOGE, FL("attr channel failed"));
4509 return -EINVAL;
4510 }
4511 pReqMsg->buckets[bktIndex].channels[j].channel =
4512 nla_get_u32(channel[
4513 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4514 hddLog(LOG1, FL("channel %u"),
4515 pReqMsg->buckets[bktIndex].channels[j].channel);
4516
4517 /* Parse and fetch dwell time */
4518 if (!channel[
4519 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4520 hddLog(LOGE, FL("attr dwelltime failed"));
4521 return -EINVAL;
4522 }
4523 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4524 nla_get_u32(channel[
4525 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4526
4527 hddLog(LOG1, FL("Dwell time (%u ms)"),
4528 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4529
4530
4531 /* Parse and fetch channel spec passive */
4532 if (!channel[
4533 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4534 hddLog(LOGE,
4535 FL("attr channel spec passive failed"));
4536 return -EINVAL;
4537 }
4538 pReqMsg->buckets[bktIndex].channels[j].passive =
4539 nla_get_u8(channel[
4540 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4541 hddLog(LOG1, FL("Chnl spec passive %u"),
4542 pReqMsg->buckets[bktIndex].channels[j].passive);
4543
4544 j++;
4545 }
4546
4547 bktIndex++;
4548 }
4549
4550 return 0;
4551}
4552
4553
4554/*
4555 * define short names for the global vendor params
4556 * used by wlan_hdd_cfg80211_extscan_start()
4557 */
4558#define PARAM_MAX \
4559QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4560#define PARAM_REQUEST_ID \
4561QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4562#define PARAM_BASE_PERIOD \
4563QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4564#define PARAM_MAX_AP_PER_SCAN \
4565QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4566#define PARAM_RPT_THRHLD_PERCENT \
4567QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4568#define PARAM_RPT_THRHLD_NUM_SCANS \
4569QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4570#define PARAM_NUM_BUCKETS \
4571QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4572
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304573static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304574 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304575 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304576{
Dino Myclee8843b32014-07-04 14:21:45 +05304577 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304578 struct net_device *dev = wdev->netdev;
4579 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4580 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4581 struct nlattr *tb[PARAM_MAX + 1];
4582 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304583 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304584 tANI_U32 request_id;
4585 struct hdd_ext_scan_context *context;
4586 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304587
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304588 ENTER();
4589
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304590 if (VOS_FTM_MODE == hdd_get_conparam()) {
4591 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4592 return -EINVAL;
4593 }
4594
Dino Mycle6fb96c12014-06-10 11:52:40 +05304595 status = wlan_hdd_validate_context(pHddCtx);
4596 if (0 != status)
4597 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304598 return -EINVAL;
4599 }
Dino Myclee8843b32014-07-04 14:21:45 +05304600 /* check the EXTScan Capability */
4601 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304602 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4603 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304604 {
4605 hddLog(VOS_TRACE_LEVEL_ERROR,
4606 FL("EXTScan not enabled/supported by Firmware"));
4607 return -EINVAL;
4608 }
4609
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304610 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304611 data, dataLen,
4612 wlan_hdd_extscan_config_policy)) {
4613 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4614 return -EINVAL;
4615 }
4616
4617 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304618 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304619 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4620 return -EINVAL;
4621 }
4622
Dino Myclee8843b32014-07-04 14:21:45 +05304623 pReqMsg = (tpSirEXTScanStartReqParams)
4624 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304625 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304626 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4627 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304628 }
4629
4630 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304631 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304632 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4633
4634 pReqMsg->sessionId = pAdapter->sessionId;
4635 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4636
4637 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304638 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304639 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4640 goto fail;
4641 }
4642 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304643 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304644 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4645 pReqMsg->basePeriod);
4646
4647 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304648 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304649 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4650 goto fail;
4651 }
4652 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304653 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304654 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4655 pReqMsg->maxAPperScan);
4656
4657 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304658 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4660 goto fail;
4661 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304662 pReqMsg->reportThresholdPercent = nla_get_u8(
4663 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304664 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304665 pReqMsg->reportThresholdPercent);
4666
4667 /* Parse and fetch report threshold num scans */
4668 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4669 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4670 goto fail;
4671 }
4672 pReqMsg->reportThresholdNumScans = nla_get_u8(
4673 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4674 hddLog(LOG1, FL("Report Threshold num scans %d"),
4675 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304676
4677 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304678 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4680 goto fail;
4681 }
4682 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304683 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304684 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4685 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4686 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4687 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4688 }
4689 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4690 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304691
Dino Mycle6fb96c12014-06-10 11:52:40 +05304692 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4693 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4694 goto fail;
4695 }
4696
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304697 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304698
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304699 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4700 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304701
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304702 context = &pHddCtx->ext_scan_context;
4703 spin_lock(&hdd_context_lock);
4704 INIT_COMPLETION(context->response_event);
4705 context->request_id = request_id = pReqMsg->requestId;
4706 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304707
Dino Mycle6fb96c12014-06-10 11:52:40 +05304708 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4709 if (!HAL_STATUS_SUCCESS(status)) {
4710 hddLog(VOS_TRACE_LEVEL_ERROR,
4711 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304712 goto fail;
4713 }
4714
4715 /* request was sent -- wait for the response */
4716 rc = wait_for_completion_timeout(&context->response_event,
4717 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4718
4719 if (!rc) {
4720 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4721 retval = -ETIMEDOUT;
4722 } else {
4723 spin_lock(&hdd_context_lock);
4724 if (context->request_id == request_id)
4725 retval = context->response_status;
4726 else
4727 retval = -EINVAL;
4728 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304729 }
4730
Dino Myclee8843b32014-07-04 14:21:45 +05304731 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304732 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304733 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304734
4735fail:
4736 vos_mem_free(pReqMsg);
4737 return -EINVAL;
4738}
4739
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304740/*
4741 * done with short names for the global vendor params
4742 * used by wlan_hdd_cfg80211_extscan_start()
4743 */
4744#undef PARAM_MAX
4745#undef PARAM_REQUEST_ID
4746#undef PARAM_BASE_PERIOD
4747#undef PARAMS_MAX_AP_PER_SCAN
4748#undef PARAMS_RPT_THRHLD_PERCENT
4749#undef PARAMS_RPT_THRHLD_NUM_SCANS
4750#undef PARAMS_NUM_BUCKETS
4751
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304752static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4753 struct wireless_dev *wdev,
4754 const void *data, int dataLen)
4755{
4756 int ret = 0;
4757
4758 vos_ssr_protect(__func__);
4759 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4760 vos_ssr_unprotect(__func__);
4761
4762 return ret;
4763}
4764
4765static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304766 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304767 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304768{
Dino Myclee8843b32014-07-04 14:21:45 +05304769 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304770 struct net_device *dev = wdev->netdev;
4771 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4772 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4773 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4774 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304775 int retval;
4776 unsigned long rc;
4777 struct hdd_ext_scan_context *context;
4778 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304779
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304780 ENTER();
4781
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304782 if (VOS_FTM_MODE == hdd_get_conparam()) {
4783 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4784 return -EINVAL;
4785 }
4786
Dino Mycle6fb96c12014-06-10 11:52:40 +05304787 status = wlan_hdd_validate_context(pHddCtx);
4788 if (0 != status)
4789 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304790 return -EINVAL;
4791 }
Dino Myclee8843b32014-07-04 14:21:45 +05304792 /* check the EXTScan Capability */
4793 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304794 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4795 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304796 {
4797 hddLog(VOS_TRACE_LEVEL_ERROR,
4798 FL("EXTScan not enabled/supported by Firmware"));
4799 return -EINVAL;
4800 }
4801
Dino Mycle6fb96c12014-06-10 11:52:40 +05304802 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4803 data, dataLen,
4804 wlan_hdd_extscan_config_policy)) {
4805 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4806 return -EINVAL;
4807 }
4808
4809 /* Parse and fetch request Id */
4810 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4812 return -EINVAL;
4813 }
4814
Dino Myclee8843b32014-07-04 14:21:45 +05304815 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304816 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304817 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304818
Dino Myclee8843b32014-07-04 14:21:45 +05304819 reqMsg.sessionId = pAdapter->sessionId;
4820 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304821
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304822 context = &pHddCtx->ext_scan_context;
4823 spin_lock(&hdd_context_lock);
4824 INIT_COMPLETION(context->response_event);
4825 context->request_id = request_id = reqMsg.sessionId;
4826 spin_unlock(&hdd_context_lock);
4827
Dino Myclee8843b32014-07-04 14:21:45 +05304828 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304829 if (!HAL_STATUS_SUCCESS(status)) {
4830 hddLog(VOS_TRACE_LEVEL_ERROR,
4831 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304832 return -EINVAL;
4833 }
4834
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304835 /* request was sent -- wait for the response */
4836 rc = wait_for_completion_timeout(&context->response_event,
4837 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4838
4839 if (!rc) {
4840 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4841 retval = -ETIMEDOUT;
4842 } else {
4843 spin_lock(&hdd_context_lock);
4844 if (context->request_id == request_id)
4845 retval = context->response_status;
4846 else
4847 retval = -EINVAL;
4848 spin_unlock(&hdd_context_lock);
4849 }
4850
4851 return retval;
4852
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304853 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304854 return 0;
4855}
4856
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304857static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4858 struct wireless_dev *wdev,
4859 const void *data, int dataLen)
4860{
4861 int ret = 0;
4862
4863 vos_ssr_protect(__func__);
4864 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4865 vos_ssr_unprotect(__func__);
4866
4867 return ret;
4868}
4869
4870static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304871 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304872 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304873{
Dino Myclee8843b32014-07-04 14:21:45 +05304874 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304875 struct net_device *dev = wdev->netdev;
4876 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4877 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4878 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4879 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304880 struct hdd_ext_scan_context *context;
4881 tANI_U32 request_id;
4882 unsigned long rc;
4883 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304884
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304885 ENTER();
4886
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304887 if (VOS_FTM_MODE == hdd_get_conparam()) {
4888 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4889 return -EINVAL;
4890 }
4891
Dino Mycle6fb96c12014-06-10 11:52:40 +05304892 status = wlan_hdd_validate_context(pHddCtx);
4893 if (0 != status)
4894 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304895 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304896 return -EINVAL;
4897 }
Dino Myclee8843b32014-07-04 14:21:45 +05304898 /* check the EXTScan Capability */
4899 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304900 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4901 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304902 {
4903 hddLog(VOS_TRACE_LEVEL_ERROR,
4904 FL("EXTScan not enabled/supported by Firmware"));
4905 return -EINVAL;
4906 }
4907
Dino Mycle6fb96c12014-06-10 11:52:40 +05304908 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4909 data, dataLen,
4910 wlan_hdd_extscan_config_policy)) {
4911 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4912 return -EINVAL;
4913 }
4914
4915 /* Parse and fetch request Id */
4916 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4918 return -EINVAL;
4919 }
4920
Dino Myclee8843b32014-07-04 14:21:45 +05304921 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304922 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304923 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304924
Dino Myclee8843b32014-07-04 14:21:45 +05304925 reqMsg.sessionId = pAdapter->sessionId;
4926 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304927
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304928 context = &pHddCtx->ext_scan_context;
4929 spin_lock(&hdd_context_lock);
4930 INIT_COMPLETION(context->response_event);
4931 context->request_id = request_id = reqMsg.requestId;
4932 spin_unlock(&hdd_context_lock);
4933
Dino Myclee8843b32014-07-04 14:21:45 +05304934 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304935 if (!HAL_STATUS_SUCCESS(status)) {
4936 hddLog(VOS_TRACE_LEVEL_ERROR,
4937 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304938 return -EINVAL;
4939 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304940
4941 /* request was sent -- wait for the response */
4942 rc = wait_for_completion_timeout(&context->response_event,
4943 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4944 if (!rc) {
4945 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4946 retval = -ETIMEDOUT;
4947 } else {
4948 spin_lock(&hdd_context_lock);
4949 if (context->request_id == request_id)
4950 retval = context->response_status;
4951 else
4952 retval = -EINVAL;
4953 spin_unlock(&hdd_context_lock);
4954 }
4955
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304956 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304957 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304958}
4959
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304960static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4961 struct wireless_dev *wdev,
4962 const void *data, int dataLen)
4963{
4964 int ret = 0;
4965
4966 vos_ssr_protect(__func__);
4967 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4968 vos_ssr_unprotect(__func__);
4969
4970 return ret;
4971}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304972#endif /* WLAN_FEATURE_EXTSCAN */
4973
Atul Mittal115287b2014-07-08 13:26:33 +05304974/*EXT TDLS*/
4975static const struct nla_policy
4976wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4977{
4978 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4979 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4980 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4981 {.type = NLA_S32 },
4982 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4983 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4984
4985};
4986
4987static const struct nla_policy
4988wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4989{
4990 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4991
4992};
4993
4994static const struct nla_policy
4995wlan_hdd_tdls_config_state_change_policy[
4996 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4997{
4998 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4999 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5000 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305001 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5002 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5003 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305004
5005};
5006
5007static const struct nla_policy
5008wlan_hdd_tdls_config_get_status_policy[
5009 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5010{
5011 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5012 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5013 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305014 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5015 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5016 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305017
5018};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305019
5020static const struct nla_policy
5021wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5022{
5023 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5024};
5025
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305026static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305027 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305028 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305029 int data_len)
5030{
5031
5032 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5033 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5034
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305035 ENTER();
5036
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305037 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305038 return -EINVAL;
5039 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305040 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305041 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305042 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305043 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305044 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305045 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305046 return -ENOTSUPP;
5047 }
5048
5049 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5050 data, data_len, wlan_hdd_mac_config)) {
5051 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5052 return -EINVAL;
5053 }
5054
5055 /* Parse and fetch mac address */
5056 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5057 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5058 return -EINVAL;
5059 }
5060
5061 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5062 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5063 VOS_MAC_ADDR_LAST_3_BYTES);
5064
Siddharth Bhal76972212014-10-15 16:22:51 +05305065 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5066
5067 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305068 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5069 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305070 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5071 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5072 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5073 {
5074 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5075 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5076 VOS_MAC_ADDRESS_LEN);
5077 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305078 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305079
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305080 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5081 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305082
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305083 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305084 return 0;
5085}
5086
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305087static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5088 struct wireless_dev *wdev,
5089 const void *data,
5090 int data_len)
5091{
5092 int ret = 0;
5093
5094 vos_ssr_protect(__func__);
5095 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5096 vos_ssr_unprotect(__func__);
5097
5098 return ret;
5099}
5100
5101static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305102 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305103 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305104 int data_len)
5105{
5106 u8 peer[6] = {0};
5107 struct net_device *dev = wdev->netdev;
5108 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5109 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5110 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5111 eHalStatus ret;
5112 tANI_S32 state;
5113 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305114 tANI_S32 global_operating_class = 0;
5115 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305116 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305117 int retVal;
5118
5119 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305120
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305121 if (!pAdapter) {
5122 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5123 return -EINVAL;
5124 }
5125
Atul Mittal115287b2014-07-08 13:26:33 +05305126 ret = wlan_hdd_validate_context(pHddCtx);
5127 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305128 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305129 return -EINVAL;
5130 }
5131 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305132 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305133 return -ENOTSUPP;
5134 }
5135 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5136 data, data_len,
5137 wlan_hdd_tdls_config_get_status_policy)) {
5138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5139 return -EINVAL;
5140 }
5141
5142 /* Parse and fetch mac address */
5143 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5145 return -EINVAL;
5146 }
5147
5148 memcpy(peer, nla_data(
5149 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5150 sizeof(peer));
5151 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5152
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305153 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305154
Atul Mittal115287b2014-07-08 13:26:33 +05305155 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305156 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305157 NLMSG_HDRLEN);
5158
5159 if (!skb) {
5160 hddLog(VOS_TRACE_LEVEL_ERROR,
5161 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5162 return -EINVAL;
5163 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305164 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05305165 reason,
5166 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305167 global_operating_class,
5168 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305169 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305170 if (nla_put_s32(skb,
5171 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5172 state) ||
5173 nla_put_s32(skb,
5174 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5175 reason) ||
5176 nla_put_s32(skb,
5177 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5178 global_operating_class) ||
5179 nla_put_s32(skb,
5180 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5181 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305182
5183 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5184 goto nla_put_failure;
5185 }
5186
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305187 retVal = cfg80211_vendor_cmd_reply(skb);
5188 EXIT();
5189 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305190
5191nla_put_failure:
5192 kfree_skb(skb);
5193 return -EINVAL;
5194}
5195
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305196static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5197 struct wireless_dev *wdev,
5198 const void *data,
5199 int data_len)
5200{
5201 int ret = 0;
5202
5203 vos_ssr_protect(__func__);
5204 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5205 vos_ssr_unprotect(__func__);
5206
5207 return ret;
5208}
5209
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305210static int wlan_hdd_cfg80211_exttdls_callback(
5211#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5212 const tANI_U8* mac,
5213#else
5214 tANI_U8* mac,
5215#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305216 tANI_S32 state,
5217 tANI_S32 reason,
5218 void *ctx)
5219{
5220 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305221 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305222 tANI_S32 global_operating_class = 0;
5223 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305224 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305225
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305226 ENTER();
5227
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305228 if (!pAdapter) {
5229 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5230 return -EINVAL;
5231 }
5232
5233 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305234 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305235 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305236 return -EINVAL;
5237 }
5238
5239 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305240 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305241 return -ENOTSUPP;
5242 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305243 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5245 NULL,
5246#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305247 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5248 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5249 GFP_KERNEL);
5250
5251 if (!skb) {
5252 hddLog(VOS_TRACE_LEVEL_ERROR,
5253 FL("cfg80211_vendor_event_alloc failed"));
5254 return -EINVAL;
5255 }
5256 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305257 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5258 reason,
5259 state,
5260 global_operating_class,
5261 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305262 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5263 MAC_ADDR_ARRAY(mac));
5264
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305265 if (nla_put(skb,
5266 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5267 VOS_MAC_ADDR_SIZE, mac) ||
5268 nla_put_s32(skb,
5269 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5270 state) ||
5271 nla_put_s32(skb,
5272 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5273 reason) ||
5274 nla_put_s32(skb,
5275 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5276 channel) ||
5277 nla_put_s32(skb,
5278 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5279 global_operating_class)
5280 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305281 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5282 goto nla_put_failure;
5283 }
5284
5285 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305286 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305287 return (0);
5288
5289nla_put_failure:
5290 kfree_skb(skb);
5291 return -EINVAL;
5292}
5293
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305294static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305295 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305296 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305297 int data_len)
5298{
5299 u8 peer[6] = {0};
5300 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305301 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5302 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5303 eHalStatus status;
5304 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305305 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305306 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305307
5308 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305309
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305310 if (!dev) {
5311 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5312 return -EINVAL;
5313 }
5314
5315 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5316 if (!pAdapter) {
5317 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5318 return -EINVAL;
5319 }
5320
Atul Mittal115287b2014-07-08 13:26:33 +05305321 status = wlan_hdd_validate_context(pHddCtx);
5322 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305324 return -EINVAL;
5325 }
5326 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305327 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305328 return -ENOTSUPP;
5329 }
5330 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5331 data, data_len,
5332 wlan_hdd_tdls_config_enable_policy)) {
5333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5334 return -EINVAL;
5335 }
5336
5337 /* Parse and fetch mac address */
5338 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5339 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5340 return -EINVAL;
5341 }
5342
5343 memcpy(peer, nla_data(
5344 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5345 sizeof(peer));
5346 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5347
5348 /* Parse and fetch channel */
5349 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5350 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5351 return -EINVAL;
5352 }
5353 pReqMsg.channel = nla_get_s32(
5354 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5355 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5356
5357 /* Parse and fetch global operating class */
5358 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5359 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5360 return -EINVAL;
5361 }
5362 pReqMsg.global_operating_class = nla_get_s32(
5363 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5364 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5365 pReqMsg.global_operating_class);
5366
5367 /* Parse and fetch latency ms */
5368 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5369 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5370 return -EINVAL;
5371 }
5372 pReqMsg.max_latency_ms = nla_get_s32(
5373 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5374 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5375 pReqMsg.max_latency_ms);
5376
5377 /* Parse and fetch required bandwidth kbps */
5378 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5379 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5380 return -EINVAL;
5381 }
5382
5383 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5384 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5385 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5386 pReqMsg.min_bandwidth_kbps);
5387
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305388 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305389 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305390 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305391 wlan_hdd_cfg80211_exttdls_callback);
5392
5393 EXIT();
5394 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305395}
5396
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305397static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5398 struct wireless_dev *wdev,
5399 const void *data,
5400 int data_len)
5401{
5402 int ret = 0;
5403
5404 vos_ssr_protect(__func__);
5405 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5406 vos_ssr_unprotect(__func__);
5407
5408 return ret;
5409}
5410
5411static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305412 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305413 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305414 int data_len)
5415{
5416 u8 peer[6] = {0};
5417 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305418 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5419 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5420 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305421 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305422 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305423
5424 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305425
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305426 if (!dev) {
5427 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5428 return -EINVAL;
5429 }
5430
5431 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5432 if (!pAdapter) {
5433 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5434 return -EINVAL;
5435 }
5436
Atul Mittal115287b2014-07-08 13:26:33 +05305437 status = wlan_hdd_validate_context(pHddCtx);
5438 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305439 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305440 return -EINVAL;
5441 }
5442 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305443 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305444 return -ENOTSUPP;
5445 }
5446 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5447 data, data_len,
5448 wlan_hdd_tdls_config_disable_policy)) {
5449 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5450 return -EINVAL;
5451 }
5452 /* Parse and fetch mac address */
5453 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5454 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5455 return -EINVAL;
5456 }
5457
5458 memcpy(peer, nla_data(
5459 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5460 sizeof(peer));
5461 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5462
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305463 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5464
5465 EXIT();
5466 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305467}
5468
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305469static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5470 struct wireless_dev *wdev,
5471 const void *data,
5472 int data_len)
5473{
5474 int ret = 0;
5475
5476 vos_ssr_protect(__func__);
5477 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5478 vos_ssr_unprotect(__func__);
5479
5480 return ret;
5481}
5482
Dasari Srinivas7875a302014-09-26 17:50:57 +05305483static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305484__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305485 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305486 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305487{
5488 struct net_device *dev = wdev->netdev;
5489 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5490 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5491 struct sk_buff *skb = NULL;
5492 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305493 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305494
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305495 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305496
5497 ret = wlan_hdd_validate_context(pHddCtx);
5498 if (0 != ret)
5499 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305500 return ret;
5501 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305502 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5503 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5504 fset |= WIFI_FEATURE_INFRA;
5505 }
5506
5507 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5508 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5509 fset |= WIFI_FEATURE_INFRA_5G;
5510 }
5511
5512#ifdef WLAN_FEATURE_P2P
5513 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5514 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5515 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5516 fset |= WIFI_FEATURE_P2P;
5517 }
5518#endif
5519
5520 /* Soft-AP is supported currently by default */
5521 fset |= WIFI_FEATURE_SOFT_AP;
5522
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305523 /* HOTSPOT is a supplicant feature, enable it by default */
5524 fset |= WIFI_FEATURE_HOTSPOT;
5525
Dasari Srinivas7875a302014-09-26 17:50:57 +05305526#ifdef WLAN_FEATURE_EXTSCAN
5527 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305528 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5529 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5530 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305531 fset |= WIFI_FEATURE_EXTSCAN;
5532 }
5533#endif
5534
Dasari Srinivas7875a302014-09-26 17:50:57 +05305535 if (sme_IsFeatureSupportedByFW(NAN)) {
5536 hddLog(LOG1, FL("NAN is supported by firmware"));
5537 fset |= WIFI_FEATURE_NAN;
5538 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305539
5540 /* D2D RTT is not supported currently by default */
5541 if (sme_IsFeatureSupportedByFW(RTT)) {
5542 hddLog(LOG1, FL("RTT is supported by firmware"));
5543 fset |= WIFI_FEATURE_D2AP_RTT;
5544 }
5545
5546#ifdef FEATURE_WLAN_BATCH_SCAN
5547 if (fset & WIFI_FEATURE_EXTSCAN) {
5548 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5549 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5550 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5551 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5552 fset |= WIFI_FEATURE_BATCH_SCAN;
5553 }
5554#endif
5555
5556#ifdef FEATURE_WLAN_SCAN_PNO
5557 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5558 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5559 hddLog(LOG1, FL("PNO is supported by firmware"));
5560 fset |= WIFI_FEATURE_PNO;
5561 }
5562#endif
5563
5564 /* STA+STA is supported currently by default */
5565 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5566
5567#ifdef FEATURE_WLAN_TDLS
5568 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5569 sme_IsFeatureSupportedByFW(TDLS)) {
5570 hddLog(LOG1, FL("TDLS is supported by firmware"));
5571 fset |= WIFI_FEATURE_TDLS;
5572 }
5573
5574 /* TDLS_OFFCHANNEL is not supported currently by default */
5575#endif
5576
5577#ifdef WLAN_AP_STA_CONCURRENCY
5578 /* AP+STA concurrency is supported currently by default */
5579 fset |= WIFI_FEATURE_AP_STA;
5580#endif
5581
Mukul Sharma5add0532015-08-17 15:57:47 +05305582#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5583 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5584 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5585#endif
5586
Dasari Srinivas7875a302014-09-26 17:50:57 +05305587 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5588 NLMSG_HDRLEN);
5589
5590 if (!skb) {
5591 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5592 return -EINVAL;
5593 }
5594 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5595
5596 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5597 hddLog(LOGE, FL("nla put fail"));
5598 goto nla_put_failure;
5599 }
5600
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305601 ret = cfg80211_vendor_cmd_reply(skb);
5602 EXIT();
5603 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305604
5605nla_put_failure:
5606 kfree_skb(skb);
5607 return -EINVAL;
5608}
5609
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305610static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305611wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5612 struct wireless_dev *wdev,
5613 const void *data, int data_len)
5614{
5615 int ret = 0;
5616
5617 vos_ssr_protect(__func__);
5618 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5619 vos_ssr_unprotect(__func__);
5620
5621 return ret;
5622}
5623
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305624
5625static const struct
5626nla_policy
5627qca_wlan_vendor_wifi_logger_get_ring_data_policy
5628[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5629 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5630 = {.type = NLA_U32 },
5631};
5632
5633static int
5634 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5635 struct wireless_dev *wdev,
5636 const void *data,
5637 int data_len)
5638{
5639 int ret;
5640 VOS_STATUS status;
5641 uint32_t ring_id;
5642 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5643 struct nlattr *tb
5644 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5645
5646 ENTER();
5647
5648 ret = wlan_hdd_validate_context(hdd_ctx);
5649 if (0 != ret) {
5650 return ret;
5651 }
5652
5653 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5654 data, data_len,
5655 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5656 hddLog(LOGE, FL("Invalid attribute"));
5657 return -EINVAL;
5658 }
5659
5660 /* Parse and fetch ring id */
5661 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5662 hddLog(LOGE, FL("attr ATTR failed"));
5663 return -EINVAL;
5664 }
5665
5666 ring_id = nla_get_u32(
5667 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5668
5669 hddLog(LOG1, FL("Bug report triggered by framework"));
5670
5671 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5672 WLAN_LOG_INDICATOR_FRAMEWORK,
5673 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305674 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305675 );
5676 if (VOS_STATUS_SUCCESS != status) {
5677 hddLog(LOGE, FL("Failed to trigger bug report"));
5678
5679 return -EINVAL;
5680 }
5681
5682 return 0;
5683
5684
5685}
5686
5687
5688static int
5689 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5690 struct wireless_dev *wdev,
5691 const void *data,
5692 int data_len)
5693{
5694 int ret = 0;
5695
5696 vos_ssr_protect(__func__);
5697 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5698 wdev, data, data_len);
5699 vos_ssr_unprotect(__func__);
5700
5701 return ret;
5702
5703}
5704
5705
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305706static int
5707__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305708 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305709 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305710{
5711 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5712 uint8_t i, feature_sets, max_feature_sets;
5713 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5714 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305715 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5716 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305717
5718 ENTER();
5719
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305720 ret = wlan_hdd_validate_context(pHddCtx);
5721 if (0 != ret)
5722 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305723 return ret;
5724 }
5725
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305726 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5727 data, data_len, NULL)) {
5728 hddLog(LOGE, FL("Invalid ATTR"));
5729 return -EINVAL;
5730 }
5731
5732 /* Parse and fetch max feature set */
5733 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5734 hddLog(LOGE, FL("Attr max feature set size failed"));
5735 return -EINVAL;
5736 }
5737 max_feature_sets = nla_get_u32(
5738 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5739 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5740
5741 /* Fill feature combination matrix */
5742 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305743 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5744 WIFI_FEATURE_P2P;
5745
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305746 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5747 WIFI_FEATURE_SOFT_AP;
5748
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305749 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5750 WIFI_FEATURE_SOFT_AP;
5751
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305752 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5753 WIFI_FEATURE_SOFT_AP |
5754 WIFI_FEATURE_P2P;
5755
5756 /* Add more feature combinations here */
5757
5758 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5759 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5760 hddLog(LOG1, "Feature set matrix");
5761 for (i = 0; i < feature_sets; i++)
5762 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5763
5764 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5765 sizeof(u32) * feature_sets +
5766 NLMSG_HDRLEN);
5767
5768 if (reply_skb) {
5769 if (nla_put_u32(reply_skb,
5770 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5771 feature_sets) ||
5772 nla_put(reply_skb,
5773 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5774 sizeof(u32) * feature_sets, feature_set_matrix)) {
5775 hddLog(LOGE, FL("nla put fail"));
5776 kfree_skb(reply_skb);
5777 return -EINVAL;
5778 }
5779
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305780 ret = cfg80211_vendor_cmd_reply(reply_skb);
5781 EXIT();
5782 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305783 }
5784 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5785 return -ENOMEM;
5786
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305787}
5788
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305789static int
5790wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5791 struct wireless_dev *wdev,
5792 const void *data, int data_len)
5793{
5794 int ret = 0;
5795
5796 vos_ssr_protect(__func__);
5797 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5798 data_len);
5799 vos_ssr_unprotect(__func__);
5800
5801 return ret;
5802}
5803
c_manjeecfd1efb2015-09-25 19:32:34 +05305804
5805static int
5806__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5807 struct wireless_dev *wdev,
5808 const void *data, int data_len)
5809{
5810 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5811 int ret;
5812 ENTER();
5813
5814 ret = wlan_hdd_validate_context(pHddCtx);
5815 if (0 != ret)
5816 {
5817 return ret;
5818 }
5819
5820 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5821 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5822 {
5823 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5824 return -EINVAL;
5825 }
5826 /*call common API for FW mem dump req*/
5827 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5828
Abhishek Singhc783fa72015-12-09 18:07:34 +05305829 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305830 {
5831 /*indicate to userspace the status of fw mem dump */
5832 wlan_indicate_mem_dump_complete(true);
5833 }
5834 else
5835 {
5836 /*else send failure to userspace */
5837 wlan_indicate_mem_dump_complete(false);
5838 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305839 EXIT();
5840 return ret;
5841}
5842
5843/**
5844 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5845 * @wiphy: pointer to wireless wiphy structure.
5846 * @wdev: pointer to wireless_dev structure.
5847 * @data: Pointer to the NL data.
5848 * @data_len:Length of @data
5849 *
5850 * This is called when wlan driver needs to get the firmware memory dump
5851 * via vendor specific command.
5852 *
5853 * Return: 0 on success, error number otherwise.
5854 */
5855
5856static int
5857wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5858 struct wireless_dev *wdev,
5859 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305860{
5861 int ret = 0;
5862 vos_ssr_protect(__func__);
5863 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5864 data_len);
5865 vos_ssr_unprotect(__func__);
5866 return ret;
5867}
c_manjeecfd1efb2015-09-25 19:32:34 +05305868
Sushant Kaushik8e644982015-09-23 12:18:54 +05305869static const struct
5870nla_policy
5871qca_wlan_vendor_wifi_logger_start_policy
5872[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5873 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5874 = {.type = NLA_U32 },
5875 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5876 = {.type = NLA_U32 },
5877 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5878 = {.type = NLA_U32 },
5879};
5880
5881/**
5882 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5883 * or disable the collection of packet statistics from the firmware
5884 * @wiphy: WIPHY structure pointer
5885 * @wdev: Wireless device structure pointer
5886 * @data: Pointer to the data received
5887 * @data_len: Length of the data received
5888 *
5889 * This function is used to enable or disable the collection of packet
5890 * statistics from the firmware
5891 *
5892 * Return: 0 on success and errno on failure
5893 */
5894static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5895 struct wireless_dev *wdev,
5896 const void *data,
5897 int data_len)
5898{
5899 eHalStatus status;
5900 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5901 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5902 tAniWifiStartLog start_log;
5903
5904 status = wlan_hdd_validate_context(hdd_ctx);
5905 if (0 != status) {
5906 return -EINVAL;
5907 }
5908
5909 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5910 data, data_len,
5911 qca_wlan_vendor_wifi_logger_start_policy)) {
5912 hddLog(LOGE, FL("Invalid attribute"));
5913 return -EINVAL;
5914 }
5915
5916 /* Parse and fetch ring id */
5917 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5918 hddLog(LOGE, FL("attr ATTR failed"));
5919 return -EINVAL;
5920 }
5921 start_log.ringId = nla_get_u32(
5922 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5923 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5924
5925 /* Parse and fetch verbose level */
5926 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5927 hddLog(LOGE, FL("attr verbose_level failed"));
5928 return -EINVAL;
5929 }
5930 start_log.verboseLevel = nla_get_u32(
5931 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5932 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5933
5934 /* Parse and fetch flag */
5935 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5936 hddLog(LOGE, FL("attr flag failed"));
5937 return -EINVAL;
5938 }
5939 start_log.flag = nla_get_u32(
5940 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5941 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5942
5943 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305944 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5945 !vos_isPktStatsEnabled()))
5946
Sushant Kaushik8e644982015-09-23 12:18:54 +05305947 {
5948 hddLog(LOGE, FL("per pkt stats not enabled"));
5949 return -EINVAL;
5950 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305951
Sushant Kaushik33200572015-08-05 16:46:20 +05305952 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305953 return 0;
5954}
5955
5956/**
5957 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5958 * or disable the collection of packet statistics from the firmware
5959 * @wiphy: WIPHY structure pointer
5960 * @wdev: Wireless device structure pointer
5961 * @data: Pointer to the data received
5962 * @data_len: Length of the data received
5963 *
5964 * This function is used to enable or disable the collection of packet
5965 * statistics from the firmware
5966 *
5967 * Return: 0 on success and errno on failure
5968 */
5969static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5970 struct wireless_dev *wdev,
5971 const void *data,
5972 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05305973{
5974 int ret = 0;
5975
5976 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305977
5978 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
5979 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05305980 vos_ssr_unprotect(__func__);
5981
5982 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05305983}
5984
5985
Agarwal Ashish738843c2014-09-25 12:27:56 +05305986static const struct nla_policy
5987wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5988 +1] =
5989{
5990 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5991};
5992
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305993static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305994 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305995 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305996 int data_len)
5997{
5998 struct net_device *dev = wdev->netdev;
5999 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6000 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6001 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6002 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6003 eHalStatus status;
6004 u32 dfsFlag = 0;
6005
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306006 ENTER();
6007
Agarwal Ashish738843c2014-09-25 12:27:56 +05306008 status = wlan_hdd_validate_context(pHddCtx);
6009 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306010 return -EINVAL;
6011 }
6012 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6013 data, data_len,
6014 wlan_hdd_set_no_dfs_flag_config_policy)) {
6015 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6016 return -EINVAL;
6017 }
6018
6019 /* Parse and fetch required bandwidth kbps */
6020 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6021 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6022 return -EINVAL;
6023 }
6024
6025 dfsFlag = nla_get_u32(
6026 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6027 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6028 dfsFlag);
6029
6030 pHddCtx->disable_dfs_flag = dfsFlag;
6031
6032 sme_disable_dfs_channel(hHal, dfsFlag);
6033 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306034
6035 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306036 return 0;
6037}
Atul Mittal115287b2014-07-08 13:26:33 +05306038
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306039static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6040 struct wireless_dev *wdev,
6041 const void *data,
6042 int data_len)
6043{
6044 int ret = 0;
6045
6046 vos_ssr_protect(__func__);
6047 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6048 vos_ssr_unprotect(__func__);
6049
6050 return ret;
6051
6052}
6053
Mukul Sharma2a271632014-10-13 14:59:01 +05306054const struct
6055nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6056{
6057 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6058 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6059};
6060
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306061static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306062 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306063{
6064
6065 u8 bssid[6] = {0};
6066 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6067 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6068 eHalStatus status = eHAL_STATUS_SUCCESS;
6069 v_U32_t isFwrRoamEnabled = FALSE;
6070 int ret;
6071
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306072 ENTER();
6073
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306074 ret = wlan_hdd_validate_context(pHddCtx);
6075 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306076 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306077 }
6078
6079 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6080 data, data_len,
6081 qca_wlan_vendor_attr);
6082 if (ret){
6083 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6084 return -EINVAL;
6085 }
6086
6087 /* Parse and fetch Enable flag */
6088 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6089 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6090 return -EINVAL;
6091 }
6092
6093 isFwrRoamEnabled = nla_get_u32(
6094 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6095
6096 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6097
6098 /* Parse and fetch bssid */
6099 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6100 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6101 return -EINVAL;
6102 }
6103
6104 memcpy(bssid, nla_data(
6105 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6106 sizeof(bssid));
6107 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6108
6109 //Update roaming
6110 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306111 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05306112 return status;
6113}
6114
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306115static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6116 struct wireless_dev *wdev, const void *data, int data_len)
6117{
6118 int ret = 0;
6119
6120 vos_ssr_protect(__func__);
6121 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6122 vos_ssr_unprotect(__func__);
6123
6124 return ret;
6125}
6126
Sushant Kaushik847890c2015-09-28 16:05:17 +05306127static const struct
6128nla_policy
6129qca_wlan_vendor_get_wifi_info_policy[
6130 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6131 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6132 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6133};
6134
6135
6136/**
6137 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6138 * @wiphy: pointer to wireless wiphy structure.
6139 * @wdev: pointer to wireless_dev structure.
6140 * @data: Pointer to the data to be passed via vendor interface
6141 * @data_len:Length of the data to be passed
6142 *
6143 * This is called when wlan driver needs to send wifi driver related info
6144 * (driver/fw version) to the user space application upon request.
6145 *
6146 * Return: Return the Success or Failure code.
6147 */
6148static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6149 struct wireless_dev *wdev,
6150 const void *data, int data_len)
6151{
6152 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6153 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6154 tSirVersionString version;
6155 uint32 version_len;
6156 uint8 attr;
6157 int status;
6158 struct sk_buff *reply_skb = NULL;
6159
6160 if (VOS_FTM_MODE == hdd_get_conparam()) {
6161 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6162 return -EINVAL;
6163 }
6164
6165 status = wlan_hdd_validate_context(hdd_ctx);
6166 if (0 != status) {
6167 hddLog(LOGE, FL("HDD context is not valid"));
6168 return -EINVAL;
6169 }
6170
6171 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6172 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6173 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6174 return -EINVAL;
6175 }
6176
6177 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6178 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6179 QWLAN_VERSIONSTR);
6180 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6181 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6182 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6183 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6184 hdd_ctx->fw_Version);
6185 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6186 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6187 } else {
6188 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6189 return -EINVAL;
6190 }
6191
6192 version_len = strlen(version);
6193 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6194 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6195 if (!reply_skb) {
6196 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6197 return -ENOMEM;
6198 }
6199
6200 if (nla_put(reply_skb, attr, version_len, version)) {
6201 hddLog(LOGE, FL("nla put fail"));
6202 kfree_skb(reply_skb);
6203 return -EINVAL;
6204 }
6205
6206 return cfg80211_vendor_cmd_reply(reply_skb);
6207}
6208
6209/**
6210 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6211 * @wiphy: pointer to wireless wiphy structure.
6212 * @wdev: pointer to wireless_dev structure.
6213 * @data: Pointer to the data to be passed via vendor interface
6214 * @data_len:Length of the data to be passed
6215 * @data_len: Length of the data received
6216 *
6217 * This function is used to enable or disable the collection of packet
6218 * statistics from the firmware
6219 *
6220 * Return: 0 on success and errno on failure
6221 */
6222
6223static int
6224wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6225 struct wireless_dev *wdev,
6226 const void *data, int data_len)
6227
6228
6229{
6230 int ret = 0;
6231
6232 vos_ssr_protect(__func__);
6233 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6234 wdev, data, data_len);
6235 vos_ssr_unprotect(__func__);
6236
6237 return ret;
6238}
6239
6240
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306241/*
6242 * define short names for the global vendor params
6243 * used by __wlan_hdd_cfg80211_monitor_rssi()
6244 */
6245#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6246#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6247#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6248#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6249#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6250
6251/**---------------------------------------------------------------------------
6252
6253 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6254 monitor start is completed successfully.
6255
6256 \return - None
6257
6258 --------------------------------------------------------------------------*/
6259void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6260{
6261 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6262
6263 if (NULL == pHddCtx)
6264 {
6265 hddLog(VOS_TRACE_LEVEL_ERROR,
6266 "%s: HDD context is NULL",__func__);
6267 return;
6268 }
6269
6270 if (VOS_STATUS_SUCCESS == status)
6271 {
6272 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6273 }
6274 else
6275 {
6276 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6277 }
6278
6279 return;
6280}
6281
6282/**---------------------------------------------------------------------------
6283
6284 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6285 stop is completed successfully.
6286
6287 \return - None
6288
6289 --------------------------------------------------------------------------*/
6290void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6291{
6292 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6293
6294 if (NULL == pHddCtx)
6295 {
6296 hddLog(VOS_TRACE_LEVEL_ERROR,
6297 "%s: HDD context is NULL",__func__);
6298 return;
6299 }
6300
6301 if (VOS_STATUS_SUCCESS == status)
6302 {
6303 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6304 }
6305 else
6306 {
6307 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6308 }
6309
6310 return;
6311}
6312
6313/**
6314 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6315 * @wiphy: Pointer to wireless phy
6316 * @wdev: Pointer to wireless device
6317 * @data: Pointer to data
6318 * @data_len: Data length
6319 *
6320 * Return: 0 on success, negative errno on failure
6321 */
6322
6323static int
6324__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6325 struct wireless_dev *wdev,
6326 const void *data,
6327 int data_len)
6328{
6329 struct net_device *dev = wdev->netdev;
6330 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6331 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6332 hdd_station_ctx_t *pHddStaCtx;
6333 struct nlattr *tb[PARAM_MAX + 1];
6334 tpSirRssiMonitorReq pReq;
6335 eHalStatus status;
6336 int ret;
6337 uint32_t control;
6338 static const struct nla_policy policy[PARAM_MAX + 1] = {
6339 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6340 [PARAM_CONTROL] = { .type = NLA_U32 },
6341 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6342 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6343 };
6344
6345 ENTER();
6346
6347 ret = wlan_hdd_validate_context(hdd_ctx);
6348 if (0 != ret) {
6349 return -EINVAL;
6350 }
6351
6352 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6353 hddLog(LOGE, FL("Not in Connected state!"));
6354 return -ENOTSUPP;
6355 }
6356
6357 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6358 hddLog(LOGE, FL("Invalid ATTR"));
6359 return -EINVAL;
6360 }
6361
6362 if (!tb[PARAM_REQUEST_ID]) {
6363 hddLog(LOGE, FL("attr request id failed"));
6364 return -EINVAL;
6365 }
6366
6367 if (!tb[PARAM_CONTROL]) {
6368 hddLog(LOGE, FL("attr control failed"));
6369 return -EINVAL;
6370 }
6371
6372 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6373
6374 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6375 if(NULL == pReq)
6376 {
6377 hddLog(LOGE,
6378 FL("vos_mem_alloc failed "));
6379 return eHAL_STATUS_FAILED_ALLOC;
6380 }
6381 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6382
6383 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6384 pReq->sessionId = pAdapter->sessionId;
6385 pReq->rssiMonitorCbContext = hdd_ctx;
6386 control = nla_get_u32(tb[PARAM_CONTROL]);
6387 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6388
6389 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6390 pReq->requestId, pReq->sessionId, control);
6391
6392 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6393 if (!tb[PARAM_MIN_RSSI]) {
6394 hddLog(LOGE, FL("attr min rssi failed"));
6395 return -EINVAL;
6396 }
6397
6398 if (!tb[PARAM_MAX_RSSI]) {
6399 hddLog(LOGE, FL("attr max rssi failed"));
6400 return -EINVAL;
6401 }
6402
6403 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6404 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6405 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6406
6407 if (!(pReq->minRssi < pReq->maxRssi)) {
6408 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6409 pReq->minRssi, pReq->maxRssi);
6410 return -EINVAL;
6411 }
6412 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6413 pReq->minRssi, pReq->maxRssi);
6414 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6415
6416 }
6417 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6418 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6419 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6420 }
6421 else {
6422 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
6423 return -EINVAL;
6424 }
6425
6426 if (!HAL_STATUS_SUCCESS(status)) {
6427 hddLog(LOGE,
6428 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
6429 return -EINVAL;
6430 }
6431
6432 return 0;
6433}
6434
6435/*
6436 * done with short names for the global vendor params
6437 * used by __wlan_hdd_cfg80211_monitor_rssi()
6438 */
6439#undef PARAM_MAX
6440#undef PARAM_CONTROL
6441#undef PARAM_REQUEST_ID
6442#undef PARAM_MAX_RSSI
6443#undef PARAM_MIN_RSSI
6444
6445/**
6446 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6447 * @wiphy: wiphy structure pointer
6448 * @wdev: Wireless device structure pointer
6449 * @data: Pointer to the data received
6450 * @data_len: Length of @data
6451 *
6452 * Return: 0 on success; errno on failure
6453 */
6454static int
6455wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6456 const void *data, int data_len)
6457{
6458 int ret;
6459
6460 vos_ssr_protect(__func__);
6461 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6462 vos_ssr_unprotect(__func__);
6463
6464 return ret;
6465}
6466
6467/**
6468 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6469 * @hddctx: HDD context
6470 * @data: rssi breached event data
6471 *
6472 * This function reads the rssi breached event %data and fill in the skb with
6473 * NL attributes and send up the NL event.
6474 * This callback execute in atomic context and must not invoke any
6475 * blocking calls.
6476 *
6477 * Return: none
6478 */
6479void hdd_rssi_threshold_breached_cb(void *hddctx,
6480 struct rssi_breach_event *data)
6481{
6482 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6483 int status;
6484 struct sk_buff *skb;
6485
6486 ENTER();
6487 status = wlan_hdd_validate_context(pHddCtx);
6488
6489 if (0 != status) {
6490 return;
6491 }
6492
6493 if (!data) {
6494 hddLog(LOGE, FL("data is null"));
6495 return;
6496 }
6497
6498 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6499#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6500 NULL,
6501#endif
6502 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6503 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6504 GFP_KERNEL);
6505
6506 if (!skb) {
6507 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6508 return;
6509 }
6510
6511 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6512 data->request_id, data->curr_rssi);
6513 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6514 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6515
6516 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6517 data->request_id) ||
6518 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6519 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6520 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6521 data->curr_rssi)) {
6522 hddLog(LOGE, FL("nla put fail"));
6523 goto fail;
6524 }
6525
6526 cfg80211_vendor_event(skb, GFP_KERNEL);
6527 return;
6528
6529fail:
6530 kfree_skb(skb);
6531 return;
6532}
6533
6534
6535
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306536/**
6537 * __wlan_hdd_cfg80211_setband() - set band
6538 * @wiphy: Pointer to wireless phy
6539 * @wdev: Pointer to wireless device
6540 * @data: Pointer to data
6541 * @data_len: Data length
6542 *
6543 * Return: 0 on success, negative errno on failure
6544 */
6545static int
6546__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6547 struct wireless_dev *wdev,
6548 const void *data,
6549 int data_len)
6550{
6551 struct net_device *dev = wdev->netdev;
6552 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6553 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6554 int ret;
6555 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6556 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6557
6558 ENTER();
6559
6560 ret = wlan_hdd_validate_context(hdd_ctx);
6561 if (0 != ret) {
6562 hddLog(LOGE, FL("HDD context is not valid"));
6563 return ret;
6564 }
6565
6566 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6567 policy)) {
6568 hddLog(LOGE, FL("Invalid ATTR"));
6569 return -EINVAL;
6570 }
6571
6572 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6573 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6574 return -EINVAL;
6575 }
6576
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306577 hdd_ctx->isSetBandByNL = TRUE;
6578 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306579 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306580 hdd_ctx->isSetBandByNL = FALSE;
6581
6582 EXIT();
6583 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306584}
6585
6586/**
6587 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6588 * @wiphy: wiphy structure pointer
6589 * @wdev: Wireless device structure pointer
6590 * @data: Pointer to the data received
6591 * @data_len: Length of @data
6592 *
6593 * Return: 0 on success; errno on failure
6594 */
6595static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6596 struct wireless_dev *wdev,
6597 const void *data,
6598 int data_len)
6599{
6600 int ret = 0;
6601
6602 vos_ssr_protect(__func__);
6603 ret = __wlan_hdd_cfg80211_setband(wiphy,
6604 wdev, data, data_len);
6605 vos_ssr_unprotect(__func__);
6606
6607 return ret;
6608}
6609
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306610#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6611/**
6612 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6613 * @hdd_ctx: HDD context
6614 * @request_id: [input] request id
6615 * @pattern_id: [output] pattern id
6616 *
6617 * This function loops through request id to pattern id array
6618 * if the slot is available, store the request id and return pattern id
6619 * if entry exists, return the pattern id
6620 *
6621 * Return: 0 on success and errno on failure
6622 */
6623static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6624 uint32_t request_id,
6625 uint8_t *pattern_id)
6626{
6627 uint32_t i;
6628
6629 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6630 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6631 {
6632 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6633 {
6634 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6635 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6636 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6637 return 0;
6638 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6639 request_id) {
6640 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6641 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6642 return 0;
6643 }
6644 }
6645 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6646 return -EINVAL;
6647}
6648
6649/**
6650 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6651 * @hdd_ctx: HDD context
6652 * @request_id: [input] request id
6653 * @pattern_id: [output] pattern id
6654 *
6655 * This function loops through request id to pattern id array
6656 * reset request id to 0 (slot available again) and
6657 * return pattern id
6658 *
6659 * Return: 0 on success and errno on failure
6660 */
6661static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6662 uint32_t request_id,
6663 uint8_t *pattern_id)
6664{
6665 uint32_t i;
6666
6667 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6668 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6669 {
6670 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6671 {
6672 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6673 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6674 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6675 return 0;
6676 }
6677 }
6678 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6679 return -EINVAL;
6680}
6681
6682
6683/*
6684 * define short names for the global vendor params
6685 * used by __wlan_hdd_cfg80211_offloaded_packets()
6686 */
6687#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6688#define PARAM_REQUEST_ID \
6689 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6690#define PARAM_CONTROL \
6691 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6692#define PARAM_IP_PACKET \
6693 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6694#define PARAM_SRC_MAC_ADDR \
6695 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6696#define PARAM_DST_MAC_ADDR \
6697 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6698#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6699
6700/**
6701 * wlan_hdd_add_tx_ptrn() - add tx pattern
6702 * @adapter: adapter pointer
6703 * @hdd_ctx: hdd context
6704 * @tb: nl attributes
6705 *
6706 * This function reads the NL attributes and forms a AddTxPtrn message
6707 * posts it to SME.
6708 *
6709 */
6710static int
6711wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6712 struct nlattr **tb)
6713{
6714 struct sSirAddPeriodicTxPtrn *add_req;
6715 eHalStatus status;
6716 uint32_t request_id, ret, len;
6717 uint8_t pattern_id = 0;
6718 v_MACADDR_t dst_addr;
6719 uint16_t eth_type = htons(ETH_P_IP);
6720
6721 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6722 {
6723 hddLog(LOGE, FL("Not in Connected state!"));
6724 return -ENOTSUPP;
6725 }
6726
6727 add_req = vos_mem_malloc(sizeof(*add_req));
6728 if (!add_req)
6729 {
6730 hddLog(LOGE, FL("memory allocation failed"));
6731 return -ENOMEM;
6732 }
6733
6734 /* Parse and fetch request Id */
6735 if (!tb[PARAM_REQUEST_ID])
6736 {
6737 hddLog(LOGE, FL("attr request id failed"));
6738 goto fail;
6739 }
6740
6741 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6742 hddLog(LOG1, FL("Request Id: %u"), request_id);
6743 if (request_id == 0)
6744 {
6745 hddLog(LOGE, FL("request_id cannot be zero"));
6746 return -EINVAL;
6747 }
6748
6749 if (!tb[PARAM_PERIOD])
6750 {
6751 hddLog(LOGE, FL("attr period failed"));
6752 goto fail;
6753 }
6754 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6755 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6756 if (add_req->usPtrnIntervalMs == 0)
6757 {
6758 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6759 goto fail;
6760 }
6761
6762 if (!tb[PARAM_SRC_MAC_ADDR])
6763 {
6764 hddLog(LOGE, FL("attr source mac address failed"));
6765 goto fail;
6766 }
6767 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6768 VOS_MAC_ADDR_SIZE);
6769 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6770 MAC_ADDR_ARRAY(add_req->macAddress));
6771
6772 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6773 VOS_MAC_ADDR_SIZE))
6774 {
6775 hddLog(LOGE,
6776 FL("input src mac address and connected ap bssid are different"));
6777 goto fail;
6778 }
6779
6780 if (!tb[PARAM_DST_MAC_ADDR])
6781 {
6782 hddLog(LOGE, FL("attr dst mac address failed"));
6783 goto fail;
6784 }
6785 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6786 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6787 MAC_ADDR_ARRAY(dst_addr.bytes));
6788
6789 if (!tb[PARAM_IP_PACKET])
6790 {
6791 hddLog(LOGE, FL("attr ip packet failed"));
6792 goto fail;
6793 }
6794 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6795 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6796
6797 if (add_req->ucPtrnSize < 0 ||
6798 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6799 HDD_ETH_HEADER_LEN))
6800 {
6801 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6802 add_req->ucPtrnSize);
6803 goto fail;
6804 }
6805
6806 len = 0;
6807 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6808 len += VOS_MAC_ADDR_SIZE;
6809 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6810 VOS_MAC_ADDR_SIZE);
6811 len += VOS_MAC_ADDR_SIZE;
6812 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6813 len += 2;
6814
6815 /*
6816 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6817 * ------------------------------------------------------------
6818 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6819 * ------------------------------------------------------------
6820 */
6821 vos_mem_copy(&add_req->ucPattern[len],
6822 nla_data(tb[PARAM_IP_PACKET]),
6823 add_req->ucPtrnSize);
6824 add_req->ucPtrnSize += len;
6825
6826 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6827 add_req->ucPattern, add_req->ucPtrnSize);
6828
6829 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6830 if (ret)
6831 {
6832 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6833 goto fail;
6834 }
6835 add_req->ucPtrnId = pattern_id;
6836 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6837
6838 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6839 if (!HAL_STATUS_SUCCESS(status))
6840 {
6841 hddLog(LOGE,
6842 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6843 goto fail;
6844 }
6845
6846 EXIT();
6847 vos_mem_free(add_req);
6848 return 0;
6849
6850fail:
6851 vos_mem_free(add_req);
6852 return -EINVAL;
6853}
6854
6855/**
6856 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6857 * @adapter: adapter pointer
6858 * @hdd_ctx: hdd context
6859 * @tb: nl attributes
6860 *
6861 * This function reads the NL attributes and forms a DelTxPtrn message
6862 * posts it to SME.
6863 *
6864 */
6865static int
6866wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6867 struct nlattr **tb)
6868{
6869 struct sSirDelPeriodicTxPtrn *del_req;
6870 eHalStatus status;
6871 uint32_t request_id, ret;
6872 uint8_t pattern_id = 0;
6873
6874 /* Parse and fetch request Id */
6875 if (!tb[PARAM_REQUEST_ID])
6876 {
6877 hddLog(LOGE, FL("attr request id failed"));
6878 return -EINVAL;
6879 }
6880 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6881 if (request_id == 0)
6882 {
6883 hddLog(LOGE, FL("request_id cannot be zero"));
6884 return -EINVAL;
6885 }
6886
6887 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6888 if (ret)
6889 {
6890 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6891 return -EINVAL;
6892 }
6893
6894 del_req = vos_mem_malloc(sizeof(*del_req));
6895 if (!del_req)
6896 {
6897 hddLog(LOGE, FL("memory allocation failed"));
6898 return -ENOMEM;
6899 }
6900
6901 vos_mem_set(del_req, sizeof(*del_req), 0);
6902 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6903 VOS_MAC_ADDR_SIZE);
6904 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6905 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6906 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6907 request_id, pattern_id, del_req->ucPatternIdBitmap);
6908
6909 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6910 if (!HAL_STATUS_SUCCESS(status))
6911 {
6912 hddLog(LOGE,
6913 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6914 goto fail;
6915 }
6916
6917 EXIT();
6918 vos_mem_free(del_req);
6919 return 0;
6920
6921fail:
6922 vos_mem_free(del_req);
6923 return -EINVAL;
6924}
6925
6926
6927/**
6928 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6929 * @wiphy: Pointer to wireless phy
6930 * @wdev: Pointer to wireless device
6931 * @data: Pointer to data
6932 * @data_len: Data length
6933 *
6934 * Return: 0 on success, negative errno on failure
6935 */
6936static int
6937__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6938 struct wireless_dev *wdev,
6939 const void *data,
6940 int data_len)
6941{
6942 struct net_device *dev = wdev->netdev;
6943 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6944 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6945 struct nlattr *tb[PARAM_MAX + 1];
6946 uint8_t control;
6947 int ret;
6948 static const struct nla_policy policy[PARAM_MAX + 1] =
6949 {
6950 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6951 [PARAM_CONTROL] = { .type = NLA_U32 },
6952 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
6953 .len = VOS_MAC_ADDR_SIZE },
6954 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
6955 .len = VOS_MAC_ADDR_SIZE },
6956 [PARAM_PERIOD] = { .type = NLA_U32 },
6957 };
6958
6959 ENTER();
6960
6961 ret = wlan_hdd_validate_context(hdd_ctx);
6962 if (0 != ret)
6963 {
6964 hddLog(LOGE, FL("HDD context is not valid"));
6965 return ret;
6966 }
6967
6968 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
6969 {
6970 hddLog(LOGE,
6971 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
6972 return -ENOTSUPP;
6973 }
6974
6975 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
6976 {
6977 hddLog(LOGE, FL("Invalid ATTR"));
6978 return -EINVAL;
6979 }
6980
6981 if (!tb[PARAM_CONTROL])
6982 {
6983 hddLog(LOGE, FL("attr control failed"));
6984 return -EINVAL;
6985 }
6986 control = nla_get_u32(tb[PARAM_CONTROL]);
6987 hddLog(LOG1, FL("Control: %d"), control);
6988
6989 if (control == WLAN_START_OFFLOADED_PACKETS)
6990 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
6991 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
6992 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
6993 else
6994 {
6995 hddLog(LOGE, FL("Invalid control: %d"), control);
6996 return -EINVAL;
6997 }
6998}
6999
7000/*
7001 * done with short names for the global vendor params
7002 * used by __wlan_hdd_cfg80211_offloaded_packets()
7003 */
7004#undef PARAM_MAX
7005#undef PARAM_REQUEST_ID
7006#undef PARAM_CONTROL
7007#undef PARAM_IP_PACKET
7008#undef PARAM_SRC_MAC_ADDR
7009#undef PARAM_DST_MAC_ADDR
7010#undef PARAM_PERIOD
7011
7012/**
7013 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7014 * @wiphy: wiphy structure pointer
7015 * @wdev: Wireless device structure pointer
7016 * @data: Pointer to the data received
7017 * @data_len: Length of @data
7018 *
7019 * Return: 0 on success; errno on failure
7020 */
7021static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7022 struct wireless_dev *wdev,
7023 const void *data,
7024 int data_len)
7025{
7026 int ret = 0;
7027
7028 vos_ssr_protect(__func__);
7029 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7030 wdev, data, data_len);
7031 vos_ssr_unprotect(__func__);
7032
7033 return ret;
7034}
7035#endif
7036
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307037static const struct
7038nla_policy
7039qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7040 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7041};
7042
7043/**
7044 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7045 * get link properties like nss, rate flags and operating frequency for
7046 * the connection with the given peer.
7047 * @wiphy: WIPHY structure pointer
7048 * @wdev: Wireless device structure pointer
7049 * @data: Pointer to the data received
7050 * @data_len: Length of the data received
7051 *
7052 * This function return the above link properties on success.
7053 *
7054 * Return: 0 on success and errno on failure
7055 */
7056static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7057 struct wireless_dev *wdev,
7058 const void *data,
7059 int data_len)
7060{
7061 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7062 struct net_device *dev = wdev->netdev;
7063 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7064 hdd_station_ctx_t *hdd_sta_ctx;
7065 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7066 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7067 uint32_t sta_id;
7068 struct sk_buff *reply_skb;
7069 uint32_t rate_flags = 0;
7070 uint8_t nss;
7071 uint8_t final_rate_flags = 0;
7072 uint32_t freq;
7073 v_CONTEXT_t pVosContext = NULL;
7074 ptSapContext pSapCtx = NULL;
7075
7076 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7077 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7078 return -EINVAL;
7079 }
7080
7081 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7082 qca_wlan_vendor_attr_policy)) {
7083 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7084 return -EINVAL;
7085 }
7086
7087 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7088 hddLog(VOS_TRACE_LEVEL_ERROR,
7089 FL("Attribute peerMac not provided for mode=%d"),
7090 adapter->device_mode);
7091 return -EINVAL;
7092 }
7093
7094 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7095 sizeof(peer_mac));
7096 hddLog(VOS_TRACE_LEVEL_INFO,
7097 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7098 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7099
7100 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7101 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7102 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7103 if ((hdd_sta_ctx->conn_info.connState !=
7104 eConnectionState_Associated) ||
7105 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7106 VOS_MAC_ADDRESS_LEN)) {
7107 hddLog(VOS_TRACE_LEVEL_ERROR,
7108 FL("Not Associated to mac "MAC_ADDRESS_STR),
7109 MAC_ADDR_ARRAY(peer_mac));
7110 return -EINVAL;
7111 }
7112
7113 nss = 1; //pronto supports only one spatial stream
7114 freq = vos_chan_to_freq(
7115 hdd_sta_ctx->conn_info.operationChannel);
7116 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7117
7118 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7119 adapter->device_mode == WLAN_HDD_SOFTAP) {
7120
7121 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7122 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7123 if(pSapCtx == NULL){
7124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7125 FL("psapCtx is NULL"));
7126 return -ENOENT;
7127 }
7128
7129
7130 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7131 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7132 !vos_is_macaddr_broadcast(
7133 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7134 vos_mem_compare(
7135 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7136 peer_mac, VOS_MAC_ADDRESS_LEN))
7137 break;
7138 }
7139
7140 if (WLAN_MAX_STA_COUNT == sta_id) {
7141 hddLog(VOS_TRACE_LEVEL_ERROR,
7142 FL("No active peer with mac="MAC_ADDRESS_STR),
7143 MAC_ADDR_ARRAY(peer_mac));
7144 return -EINVAL;
7145 }
7146
7147 nss = 1; //pronto supports only one spatial stream
7148 freq = vos_chan_to_freq(
7149 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7150 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7151 } else {
7152 hddLog(VOS_TRACE_LEVEL_ERROR,
7153 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7154 MAC_ADDR_ARRAY(peer_mac));
7155 return -EINVAL;
7156 }
7157
7158 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7159 if (rate_flags & eHAL_TX_RATE_VHT80) {
7160 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7161 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7162 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7163 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7164 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7165 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7166 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7167 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7168 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7169 if (rate_flags & eHAL_TX_RATE_HT40)
7170 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7171 }
7172
7173 if (rate_flags & eHAL_TX_RATE_SGI) {
7174 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7175 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7176 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7177 }
7178 }
7179
7180 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7181 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7182
7183 if (NULL == reply_skb) {
7184 hddLog(VOS_TRACE_LEVEL_ERROR,
7185 FL("getLinkProperties: skb alloc failed"));
7186 return -EINVAL;
7187 }
7188
7189 if (nla_put_u8(reply_skb,
7190 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7191 nss) ||
7192 nla_put_u8(reply_skb,
7193 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7194 final_rate_flags) ||
7195 nla_put_u32(reply_skb,
7196 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7197 freq)) {
7198 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7199 kfree_skb(reply_skb);
7200 return -EINVAL;
7201 }
7202
7203 return cfg80211_vendor_cmd_reply(reply_skb);
7204}
7205
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307206#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7207#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7208#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7209#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
7210
7211/**
7212 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7213 * vendor command
7214 *
7215 * @wiphy: wiphy device pointer
7216 * @wdev: wireless device pointer
7217 * @data: Vendor command data buffer
7218 * @data_len: Buffer length
7219 *
7220 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7221 *
7222 * Return: EOK or other error codes.
7223 */
7224
7225static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7226 struct wireless_dev *wdev,
7227 const void *data,
7228 int data_len)
7229{
7230 struct net_device *dev = wdev->netdev;
7231 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7232 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7233 hdd_station_ctx_t *pHddStaCtx;
7234 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7235 tpSetWifiConfigParams pReq;
7236 eHalStatus status;
7237 int ret_val;
7238 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7239 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7240 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
7241 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7242 };
7243
7244 ENTER();
7245
7246 if (VOS_FTM_MODE == hdd_get_conparam()) {
7247 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7248 return -EINVAL;
7249 }
7250
7251 ret_val = wlan_hdd_validate_context(pHddCtx);
7252 if (ret_val) {
7253 return ret_val;
7254 }
7255
7256 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7257
7258 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7259 hddLog(LOGE, FL("Not in Connected state!"));
7260 return -ENOTSUPP;
7261 }
7262
7263 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7264 hddLog(LOGE, FL("Invalid ATTR"));
7265 return -EINVAL;
7266 }
7267
7268 /* check the Wifi Capability */
7269 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7270 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7271 {
7272 hddLog(VOS_TRACE_LEVEL_ERROR,
7273 FL("WIFICONFIG not supported by Firmware"));
7274 return -EINVAL;
7275 }
7276
7277 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
7278
7279 if (!pReq) {
7280 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7281 "%s: Not able to allocate memory for tSetWifiConfigParams",
7282 __func__);
7283 return eHAL_STATUS_E_MALLOC_FAILED;
7284 }
7285
7286 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7287
7288 pReq->sessionId = pAdapter->sessionId;
7289 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7290
7291 if (tb[PARAM_MODULATED_DTIM]) {
7292 pReq->paramValue = nla_get_u32(
7293 tb[PARAM_MODULATED_DTIM]);
7294 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7295 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307296 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307297 hdd_set_pwrparams(pHddCtx);
7298 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7299 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7300
7301 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7302 iw_full_power_cbfn, pAdapter,
7303 eSME_FULL_PWR_NEEDED_BY_HDD);
7304 }
7305 else
7306 {
7307 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7308 }
7309 }
7310
7311 if (tb[PARAM_STATS_AVG_FACTOR]) {
7312 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7313 pReq->paramValue = nla_get_u16(
7314 tb[PARAM_STATS_AVG_FACTOR]);
7315 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7316 pReq->paramType, pReq->paramValue);
7317 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7318
7319 if (eHAL_STATUS_SUCCESS != status)
7320 {
7321 vos_mem_free(pReq);
7322 pReq = NULL;
7323 ret_val = -EPERM;
7324 return ret_val;
7325 }
7326 }
7327
7328
7329 if (tb[PARAM_GUARD_TIME]) {
7330 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7331 pReq->paramValue = nla_get_u32(
7332 tb[PARAM_GUARD_TIME]);
7333 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7334 pReq->paramType, pReq->paramValue);
7335 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7336
7337 if (eHAL_STATUS_SUCCESS != status)
7338 {
7339 vos_mem_free(pReq);
7340 pReq = NULL;
7341 ret_val = -EPERM;
7342 return ret_val;
7343 }
7344
7345 }
7346
7347 EXIT();
7348 return ret_val;
7349}
7350
7351/**
7352 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7353 * vendor command
7354 *
7355 * @wiphy: wiphy device pointer
7356 * @wdev: wireless device pointer
7357 * @data: Vendor command data buffer
7358 * @data_len: Buffer length
7359 *
7360 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7361 *
7362 * Return: EOK or other error codes.
7363 */
7364static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7365 struct wireless_dev *wdev,
7366 const void *data,
7367 int data_len)
7368{
7369 int ret;
7370
7371 vos_ssr_protect(__func__);
7372 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7373 data, data_len);
7374 vos_ssr_unprotect(__func__);
7375
7376 return ret;
7377}
Sunil Duttc69bccb2014-05-26 21:30:20 +05307378const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7379{
Mukul Sharma2a271632014-10-13 14:59:01 +05307380 {
7381 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7382 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7383 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7384 WIPHY_VENDOR_CMD_NEED_NETDEV |
7385 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307386 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307387 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307388
7389 {
7390 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7391 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7392 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7393 WIPHY_VENDOR_CMD_NEED_NETDEV |
7394 WIPHY_VENDOR_CMD_NEED_RUNNING,
7395 .doit = wlan_hdd_cfg80211_nan_request
7396 },
7397
Sunil Duttc69bccb2014-05-26 21:30:20 +05307398#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7399 {
7400 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7401 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7402 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7403 WIPHY_VENDOR_CMD_NEED_NETDEV |
7404 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307405 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307406 },
7407
7408 {
7409 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7410 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7411 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7412 WIPHY_VENDOR_CMD_NEED_NETDEV |
7413 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307414 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307415 },
7416
7417 {
7418 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7419 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7420 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7421 WIPHY_VENDOR_CMD_NEED_NETDEV |
7422 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307423 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307424 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307425#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307426#ifdef WLAN_FEATURE_EXTSCAN
7427 {
7428 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7429 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7430 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7431 WIPHY_VENDOR_CMD_NEED_NETDEV |
7432 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307433 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307434 },
7435 {
7436 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7437 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7438 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7439 WIPHY_VENDOR_CMD_NEED_NETDEV |
7440 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307441 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307442 },
7443 {
7444 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7445 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7446 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7447 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307448 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307449 },
7450 {
7451 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7452 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7453 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7454 WIPHY_VENDOR_CMD_NEED_NETDEV |
7455 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307456 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307457 },
7458 {
7459 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7460 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7461 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7462 WIPHY_VENDOR_CMD_NEED_NETDEV |
7463 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307464 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307465 },
7466 {
7467 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7468 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7469 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7470 WIPHY_VENDOR_CMD_NEED_NETDEV |
7471 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307472 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307473 },
7474 {
7475 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7476 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7477 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7478 WIPHY_VENDOR_CMD_NEED_NETDEV |
7479 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307480 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307481 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307482 {
7483 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7484 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7485 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7486 WIPHY_VENDOR_CMD_NEED_NETDEV |
7487 WIPHY_VENDOR_CMD_NEED_RUNNING,
7488 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7489 },
7490 {
7491 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7492 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7493 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7494 WIPHY_VENDOR_CMD_NEED_NETDEV |
7495 WIPHY_VENDOR_CMD_NEED_RUNNING,
7496 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7497 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307498#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307499/*EXT TDLS*/
7500 {
7501 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7502 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7503 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7504 WIPHY_VENDOR_CMD_NEED_NETDEV |
7505 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307506 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307507 },
7508 {
7509 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7510 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7511 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7512 WIPHY_VENDOR_CMD_NEED_NETDEV |
7513 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307514 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307515 },
7516 {
7517 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7518 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7519 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7520 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307521 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307522 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307523 {
7524 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7525 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7526 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7527 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307528 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307529 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307530 {
7531 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7532 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7533 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7534 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307535 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307536 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307537 {
7538 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7539 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7540 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7541 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307542 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307543 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307544 {
7545 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7546 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7547 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7548 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307549 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307550 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307551 {
7552 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307553 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7554 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7555 WIPHY_VENDOR_CMD_NEED_NETDEV |
7556 WIPHY_VENDOR_CMD_NEED_RUNNING,
7557 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7558 },
7559 {
7560 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307561 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7562 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7563 WIPHY_VENDOR_CMD_NEED_NETDEV |
7564 WIPHY_VENDOR_CMD_NEED_RUNNING,
7565 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307566 },
7567 {
7568 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7569 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7570 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7571 WIPHY_VENDOR_CMD_NEED_NETDEV,
7572 .doit = wlan_hdd_cfg80211_wifi_logger_start
7573 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307574 {
7575 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7576 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7577 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7578 WIPHY_VENDOR_CMD_NEED_NETDEV|
7579 WIPHY_VENDOR_CMD_NEED_RUNNING,
7580 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307581 },
7582 {
7583 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7584 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7585 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7586 WIPHY_VENDOR_CMD_NEED_NETDEV |
7587 WIPHY_VENDOR_CMD_NEED_RUNNING,
7588 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307589 },
7590 {
7591 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7592 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7593 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7594 WIPHY_VENDOR_CMD_NEED_NETDEV |
7595 WIPHY_VENDOR_CMD_NEED_RUNNING,
7596 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307597 },
7598#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7599 {
7600 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7601 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7602 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7603 WIPHY_VENDOR_CMD_NEED_NETDEV |
7604 WIPHY_VENDOR_CMD_NEED_RUNNING,
7605 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307606 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307607#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307608 {
7609 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7610 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7611 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7612 WIPHY_VENDOR_CMD_NEED_NETDEV |
7613 WIPHY_VENDOR_CMD_NEED_RUNNING,
7614 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307615 },
7616 {
7617 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7618 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7619 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7620 WIPHY_VENDOR_CMD_NEED_NETDEV |
7621 WIPHY_VENDOR_CMD_NEED_RUNNING,
7622 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307623 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05307624};
7625
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007626/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307627static const
7628struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007629{
7630#ifdef FEATURE_WLAN_CH_AVOID
7631 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307632 .vendor_id = QCA_NL80211_VENDOR_ID,
7633 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007634 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307635#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7636#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7637 {
7638 /* Index = 1*/
7639 .vendor_id = QCA_NL80211_VENDOR_ID,
7640 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7641 },
7642 {
7643 /* Index = 2*/
7644 .vendor_id = QCA_NL80211_VENDOR_ID,
7645 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7646 },
7647 {
7648 /* Index = 3*/
7649 .vendor_id = QCA_NL80211_VENDOR_ID,
7650 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7651 },
7652 {
7653 /* Index = 4*/
7654 .vendor_id = QCA_NL80211_VENDOR_ID,
7655 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7656 },
7657 {
7658 /* Index = 5*/
7659 .vendor_id = QCA_NL80211_VENDOR_ID,
7660 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7661 },
7662 {
7663 /* Index = 6*/
7664 .vendor_id = QCA_NL80211_VENDOR_ID,
7665 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7666 },
7667#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307668#ifdef WLAN_FEATURE_EXTSCAN
7669 {
7670 .vendor_id = QCA_NL80211_VENDOR_ID,
7671 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7672 },
7673 {
7674 .vendor_id = QCA_NL80211_VENDOR_ID,
7675 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7676 },
7677 {
7678 .vendor_id = QCA_NL80211_VENDOR_ID,
7679 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7680 },
7681 {
7682 .vendor_id = QCA_NL80211_VENDOR_ID,
7683 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7684 },
7685 {
7686 .vendor_id = QCA_NL80211_VENDOR_ID,
7687 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7688 },
7689 {
7690 .vendor_id = QCA_NL80211_VENDOR_ID,
7691 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7692 },
7693 {
7694 .vendor_id = QCA_NL80211_VENDOR_ID,
7695 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7696 },
7697 {
7698 .vendor_id = QCA_NL80211_VENDOR_ID,
7699 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7700 },
7701 {
7702 .vendor_id = QCA_NL80211_VENDOR_ID,
7703 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7704 },
7705 {
7706 .vendor_id = QCA_NL80211_VENDOR_ID,
7707 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7708 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307709 {
7710 .vendor_id = QCA_NL80211_VENDOR_ID,
7711 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7712 },
7713 {
7714 .vendor_id = QCA_NL80211_VENDOR_ID,
7715 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7716 },
7717 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7718 .vendor_id = QCA_NL80211_VENDOR_ID,
7719 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7720 },
7721 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7722 .vendor_id = QCA_NL80211_VENDOR_ID,
7723 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7724 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307725#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307726/*EXT TDLS*/
7727 {
7728 .vendor_id = QCA_NL80211_VENDOR_ID,
7729 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7730 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307731 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7732 .vendor_id = QCA_NL80211_VENDOR_ID,
7733 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7734 },
7735
Srinivas Dasari030bad32015-02-18 23:23:54 +05307736
7737 {
7738 .vendor_id = QCA_NL80211_VENDOR_ID,
7739 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7740 },
7741
Sushant Kaushik084f6592015-09-10 13:11:56 +05307742 {
7743 .vendor_id = QCA_NL80211_VENDOR_ID,
7744 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307745 },
7746 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7747 .vendor_id = QCA_NL80211_VENDOR_ID,
7748 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7749 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307750
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007751};
7752
Jeff Johnson295189b2012-06-20 16:38:30 -07007753/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307754 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307755 * This function is called by hdd_wlan_startup()
7756 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307757 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007758 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307759struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007760{
7761 struct wiphy *wiphy;
7762 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307763 /*
7764 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007765 */
7766 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7767
7768 if (!wiphy)
7769 {
7770 /* Print error and jump into err label and free the memory */
7771 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7772 return NULL;
7773 }
7774
Sunil Duttc69bccb2014-05-26 21:30:20 +05307775
Jeff Johnson295189b2012-06-20 16:38:30 -07007776 return wiphy;
7777}
7778
7779/*
7780 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307781 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007782 * private ioctl to change the band value
7783 */
7784int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7785{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307786 int i, j;
7787 eNVChannelEnabledType channelEnabledState;
7788
Jeff Johnsone7245742012-09-05 17:12:55 -07007789 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307790
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307791 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007792 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307793
7794 if (NULL == wiphy->bands[i])
7795 {
7796 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7797 __func__, i);
7798 continue;
7799 }
7800
7801 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7802 {
7803 struct ieee80211_supported_band *band = wiphy->bands[i];
7804
7805 channelEnabledState = vos_nv_getChannelEnabledState(
7806 band->channels[j].hw_value);
7807
7808 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7809 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307810 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307811 continue;
7812 }
7813 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7814 {
7815 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7816 continue;
7817 }
7818
7819 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7820 NV_CHANNEL_INVALID == channelEnabledState)
7821 {
7822 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7823 }
7824 else if (NV_CHANNEL_DFS == channelEnabledState)
7825 {
7826 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7827 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7828 }
7829 else
7830 {
7831 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7832 |IEEE80211_CHAN_RADAR);
7833 }
7834 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007835 }
7836 return 0;
7837}
7838/*
7839 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307840 * This function is called by hdd_wlan_startup()
7841 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007842 * This function is used to initialize and register wiphy structure.
7843 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307844int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007845 struct wiphy *wiphy,
7846 hdd_config_t *pCfg
7847 )
7848{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307849 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307850 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7851
Jeff Johnsone7245742012-09-05 17:12:55 -07007852 ENTER();
7853
Jeff Johnson295189b2012-06-20 16:38:30 -07007854 /* Now bind the underlying wlan device with wiphy */
7855 set_wiphy_dev(wiphy, dev);
7856
7857 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007858
Kiet Lam6c583332013-10-14 05:37:09 +05307859#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007860 /* the flag for the other case would be initialzed in
7861 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07007862 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307863#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007864
Amar Singhalfddc28c2013-09-05 13:03:40 -07007865 /* This will disable updating of NL channels from passive to
7866 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307867#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7868 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7869#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007870 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307871#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007872
Amar Singhala49cbc52013-10-08 18:37:44 -07007873
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007874#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007875 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7876 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7877 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007878 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307879#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7880 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
7881#else
7882 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7883#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007884#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007885
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007886#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007887 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007888#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007889 || pCfg->isFastRoamIniFeatureEnabled
7890#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007891#ifdef FEATURE_WLAN_ESE
7892 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007893#endif
7894 )
7895 {
7896 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7897 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007898#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007899#ifdef FEATURE_WLAN_TDLS
7900 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7901 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7902#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307903#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307904 if (pCfg->configPNOScanSupport)
7905 {
7906 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7907 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7908 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7909 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7910 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307911#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007912
Abhishek Singh10d85972015-04-17 10:27:23 +05307913#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7914 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7915#endif
7916
Amar Singhalfddc28c2013-09-05 13:03:40 -07007917#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007918 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
7919 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07007920 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007921 driver need to determine what to do with both
7922 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07007923
7924 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07007925#else
7926 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007927#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007928
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307929 wiphy->max_scan_ssids = MAX_SCAN_SSID;
7930
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05307931 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07007932
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307933 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
7934
Jeff Johnson295189b2012-06-20 16:38:30 -07007935 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05307936 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
7937 | BIT(NL80211_IFTYPE_ADHOC)
7938 | BIT(NL80211_IFTYPE_P2P_CLIENT)
7939 | BIT(NL80211_IFTYPE_P2P_GO)
7940 | BIT(NL80211_IFTYPE_AP);
7941
7942 if (VOS_MONITOR_MODE == hdd_get_conparam())
7943 {
7944 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
7945 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007946
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307947 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007948 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307949#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7950 if( pCfg->enableMCC )
7951 {
7952 /* Currently, supports up to two channels */
7953 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007954
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307955 if( !pCfg->allowMCCGODiffBI )
7956 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007957
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307958 }
7959 wiphy->iface_combinations = &wlan_hdd_iface_combination;
7960 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007961#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307962 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007963
Jeff Johnson295189b2012-06-20 16:38:30 -07007964 /* Before registering we need to update the ht capabilitied based
7965 * on ini values*/
7966 if( !pCfg->ShortGI20MhzEnable )
7967 {
7968 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7969 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07007970 }
7971
7972 if( !pCfg->ShortGI40MhzEnable )
7973 {
7974 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
7975 }
7976
7977 if( !pCfg->nChannelBondingMode5GHz )
7978 {
7979 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
7980 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05307981 /*
7982 * In case of static linked driver at the time of driver unload,
7983 * module exit doesn't happens. Module cleanup helps in cleaning
7984 * of static memory.
7985 * If driver load happens statically, at the time of driver unload,
7986 * wiphy flags don't get reset because of static memory.
7987 * It's better not to store channel in static memory.
7988 */
7989 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
7990 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
7991 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
7992 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
7993 {
7994 hddLog(VOS_TRACE_LEVEL_ERROR,
7995 FL("Not enough memory to allocate channels"));
7996 return -ENOMEM;
7997 }
7998 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
7999 &hdd_channels_2_4_GHZ[0],
8000 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008001
Agrawal Ashish97dec502015-11-26 20:20:58 +05308002 if (true == hdd_is_5g_supported(pHddCtx))
8003 {
8004 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8005 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8006 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8007 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8008 {
8009 hddLog(VOS_TRACE_LEVEL_ERROR,
8010 FL("Not enough memory to allocate channels"));
8011 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8012 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8013 return -ENOMEM;
8014 }
8015 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8016 &hdd_channels_5_GHZ[0],
8017 sizeof(hdd_channels_5_GHZ));
8018 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308019
8020 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8021 {
8022
8023 if (NULL == wiphy->bands[i])
8024 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308025 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308026 __func__, i);
8027 continue;
8028 }
8029
8030 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8031 {
8032 struct ieee80211_supported_band *band = wiphy->bands[i];
8033
8034 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8035 {
8036 // Enable social channels for P2P
8037 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8038 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8039 else
8040 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8041 continue;
8042 }
8043 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8044 {
8045 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8046 continue;
8047 }
8048 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008049 }
8050 /*Initialise the supported cipher suite details*/
8051 wiphy->cipher_suites = hdd_cipher_suites;
8052 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8053
8054 /*signal strength in mBm (100*dBm) */
8055 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8056
8057#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308058 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008059#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008060
Sunil Duttc69bccb2014-05-26 21:30:20 +05308061 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8062 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008063 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8064 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8065
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308066 EXIT();
8067 return 0;
8068}
8069
8070/* In this function we are registering wiphy. */
8071int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8072{
8073 ENTER();
8074 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008075 if (0 > wiphy_register(wiphy))
8076 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308077 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008078 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8079 return -EIO;
8080 }
8081
8082 EXIT();
8083 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308084}
Jeff Johnson295189b2012-06-20 16:38:30 -07008085
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308086/* In this function we are updating channel list when,
8087 regulatory domain is FCC and country code is US.
8088 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8089 As per FCC smart phone is not a indoor device.
8090 GO should not opeate on indoor channels */
8091void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8092{
8093 int j;
8094 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8095 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8096 //Default counrtycode from NV at the time of wiphy initialization.
8097 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8098 &defaultCountryCode[0]))
8099 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008100 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308101 }
8102 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8103 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308104 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8105 {
8106 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8107 return;
8108 }
8109 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8110 {
8111 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8112 // Mark UNII -1 band channel as passive
8113 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8114 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8115 }
8116 }
8117}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308118/* This function registers for all frame which supplicant is interested in */
8119void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008120{
Jeff Johnson295189b2012-06-20 16:38:30 -07008121 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8122 /* Register for all P2P action, public action etc frames */
8123 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008124 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308125 /* Register frame indication call back */
8126 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008127 /* Right now we are registering these frame when driver is getting
8128 initialized. Once we will move to 2.6.37 kernel, in which we have
8129 frame register ops, we will move this code as a part of that */
8130 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308131 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008132 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8133
8134 /* GAS Initial Response */
8135 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8136 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308137
Jeff Johnson295189b2012-06-20 16:38:30 -07008138 /* GAS Comeback Request */
8139 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8140 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8141
8142 /* GAS Comeback Response */
8143 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8144 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8145
8146 /* P2P Public Action */
8147 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308148 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008149 P2P_PUBLIC_ACTION_FRAME_SIZE );
8150
8151 /* P2P Action */
8152 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8153 (v_U8_t*)P2P_ACTION_FRAME,
8154 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008155
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308156 /* WNM BSS Transition Request frame */
8157 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8158 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8159 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008160
8161 /* WNM-Notification */
8162 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8163 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8164 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008165}
8166
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308167void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008168{
Jeff Johnson295189b2012-06-20 16:38:30 -07008169 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8170 /* Register for all P2P action, public action etc frames */
8171 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8172
Jeff Johnsone7245742012-09-05 17:12:55 -07008173 ENTER();
8174
Jeff Johnson295189b2012-06-20 16:38:30 -07008175 /* Right now we are registering these frame when driver is getting
8176 initialized. Once we will move to 2.6.37 kernel, in which we have
8177 frame register ops, we will move this code as a part of that */
8178 /* GAS Initial Request */
8179
8180 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8181 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8182
8183 /* GAS Initial Response */
8184 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8185 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308186
Jeff Johnson295189b2012-06-20 16:38:30 -07008187 /* GAS Comeback Request */
8188 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8189 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8190
8191 /* GAS Comeback Response */
8192 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8193 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8194
8195 /* P2P Public Action */
8196 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308197 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008198 P2P_PUBLIC_ACTION_FRAME_SIZE );
8199
8200 /* P2P Action */
8201 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8202 (v_U8_t*)P2P_ACTION_FRAME,
8203 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008204 /* WNM-Notification */
8205 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8206 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8207 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008208}
8209
8210#ifdef FEATURE_WLAN_WAPI
8211void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308212 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008213{
8214 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8215 tCsrRoamSetKey setKey;
8216 v_BOOL_t isConnected = TRUE;
8217 int status = 0;
8218 v_U32_t roamId= 0xFF;
8219 tANI_U8 *pKeyPtr = NULL;
8220 int n = 0;
8221
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308222 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8223 __func__, hdd_device_modetoString(pAdapter->device_mode),
8224 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008225
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308226 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008227 setKey.keyId = key_index; // Store Key ID
8228 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8229 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8230 setKey.paeRole = 0 ; // the PAE role
8231 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8232 {
8233 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8234 }
8235 else
8236 {
8237 isConnected = hdd_connIsConnected(pHddStaCtx);
8238 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8239 }
8240 setKey.keyLength = key_Len;
8241 pKeyPtr = setKey.Key;
8242 memcpy( pKeyPtr, key, key_Len);
8243
Arif Hussain6d2a3322013-11-17 19:50:10 -08008244 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008245 __func__, key_Len);
8246 for (n = 0 ; n < key_Len; n++)
8247 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8248 __func__,n,setKey.Key[n]);
8249
8250 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8251 if ( isConnected )
8252 {
8253 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8254 pAdapter->sessionId, &setKey, &roamId );
8255 }
8256 if ( status != 0 )
8257 {
8258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8259 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8260 __LINE__, status );
8261 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8262 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308263 /* Need to clear any trace of key value in the memory.
8264 * Thus zero out the memory even though it is local
8265 * variable.
8266 */
8267 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008268}
8269#endif /* FEATURE_WLAN_WAPI*/
8270
8271#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308272int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008273 beacon_data_t **ppBeacon,
8274 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008275#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308276int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008277 beacon_data_t **ppBeacon,
8278 struct cfg80211_beacon_data *params,
8279 int dtim_period)
8280#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308281{
Jeff Johnson295189b2012-06-20 16:38:30 -07008282 int size;
8283 beacon_data_t *beacon = NULL;
8284 beacon_data_t *old = NULL;
8285 int head_len,tail_len;
8286
Jeff Johnsone7245742012-09-05 17:12:55 -07008287 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008288 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308289 {
8290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8291 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008292 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308293 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008294
8295 old = pAdapter->sessionCtx.ap.beacon;
8296
8297 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308298 {
8299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8300 FL("session(%d) old and new heads points to NULL"),
8301 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008302 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308303 }
8304
8305 if (params->tail && !params->tail_len)
8306 {
8307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8308 FL("tail_len is zero but tail is not NULL"));
8309 return -EINVAL;
8310 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008311
Jeff Johnson295189b2012-06-20 16:38:30 -07008312#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8313 /* Kernel 3.0 is not updating dtim_period for set beacon */
8314 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308315 {
8316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8317 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008318 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308319 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008320#endif
8321
8322 if(params->head)
8323 head_len = params->head_len;
8324 else
8325 head_len = old->head_len;
8326
8327 if(params->tail || !old)
8328 tail_len = params->tail_len;
8329 else
8330 tail_len = old->tail_len;
8331
8332 size = sizeof(beacon_data_t) + head_len + tail_len;
8333
8334 beacon = kzalloc(size, GFP_KERNEL);
8335
8336 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308337 {
8338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8339 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008340 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308341 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008342
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008343#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008344 if(params->dtim_period || !old )
8345 beacon->dtim_period = params->dtim_period;
8346 else
8347 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008348#else
8349 if(dtim_period || !old )
8350 beacon->dtim_period = dtim_period;
8351 else
8352 beacon->dtim_period = old->dtim_period;
8353#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308354
Jeff Johnson295189b2012-06-20 16:38:30 -07008355 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8356 beacon->tail = beacon->head + head_len;
8357 beacon->head_len = head_len;
8358 beacon->tail_len = tail_len;
8359
8360 if(params->head) {
8361 memcpy (beacon->head,params->head,beacon->head_len);
8362 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308363 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07008364 if(old)
8365 memcpy (beacon->head,old->head,beacon->head_len);
8366 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308367
Jeff Johnson295189b2012-06-20 16:38:30 -07008368 if(params->tail) {
8369 memcpy (beacon->tail,params->tail,beacon->tail_len);
8370 }
8371 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308372 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07008373 memcpy (beacon->tail,old->tail,beacon->tail_len);
8374 }
8375
8376 *ppBeacon = beacon;
8377
8378 kfree(old);
8379
8380 return 0;
8381
8382}
Jeff Johnson295189b2012-06-20 16:38:30 -07008383
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308384v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8385#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8386 const v_U8_t *pIes,
8387#else
8388 v_U8_t *pIes,
8389#endif
8390 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008391{
8392 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308393 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008394 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308395
Jeff Johnson295189b2012-06-20 16:38:30 -07008396 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308397 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008398 elem_id = ptr[0];
8399 elem_len = ptr[1];
8400 left -= 2;
8401 if(elem_len > left)
8402 {
8403 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008404 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008405 eid,elem_len,left);
8406 return NULL;
8407 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308408 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008409 {
8410 return ptr;
8411 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308412
Jeff Johnson295189b2012-06-20 16:38:30 -07008413 left -= elem_len;
8414 ptr += (elem_len + 2);
8415 }
8416 return NULL;
8417}
8418
Jeff Johnson295189b2012-06-20 16:38:30 -07008419/* Check if rate is 11g rate or not */
8420static int wlan_hdd_rate_is_11g(u8 rate)
8421{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008422 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008423 u8 i;
8424 for (i = 0; i < 8; i++)
8425 {
8426 if(rate == gRateArray[i])
8427 return TRUE;
8428 }
8429 return FALSE;
8430}
8431
8432/* Check for 11g rate and set proper 11g only mode */
8433static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8434 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8435{
8436 u8 i, num_rates = pIe[0];
8437
8438 pIe += 1;
8439 for ( i = 0; i < num_rates; i++)
8440 {
8441 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8442 {
8443 /* If rate set have 11g rate than change the mode to 11G */
8444 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8445 if (pIe[i] & BASIC_RATE_MASK)
8446 {
8447 /* If we have 11g rate as basic rate, it means mode
8448 is 11g only mode.
8449 */
8450 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8451 *pCheckRatesfor11g = FALSE;
8452 }
8453 }
8454 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8455 {
8456 *require_ht = TRUE;
8457 }
8458 }
8459 return;
8460}
8461
8462static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8463{
8464 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8465 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8466 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8467 u8 checkRatesfor11g = TRUE;
8468 u8 require_ht = FALSE;
8469 u8 *pIe=NULL;
8470
8471 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8472
8473 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8474 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8475 if (pIe != NULL)
8476 {
8477 pIe += 1;
8478 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8479 &pConfig->SapHw_mode);
8480 }
8481
8482 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8483 WLAN_EID_EXT_SUPP_RATES);
8484 if (pIe != NULL)
8485 {
8486
8487 pIe += 1;
8488 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8489 &pConfig->SapHw_mode);
8490 }
8491
8492 if( pConfig->channel > 14 )
8493 {
8494 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8495 }
8496
8497 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8498 WLAN_EID_HT_CAPABILITY);
8499
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308500 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008501 {
8502 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8503 if(require_ht)
8504 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8505 }
8506}
8507
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308508static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8509 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8510{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008511 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308512 v_U8_t *pIe = NULL;
8513 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8514
8515 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8516 pBeacon->tail, pBeacon->tail_len);
8517
8518 if (pIe)
8519 {
8520 ielen = pIe[1] + 2;
8521 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8522 {
8523 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8524 }
8525 else
8526 {
8527 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8528 return -EINVAL;
8529 }
8530 *total_ielen += ielen;
8531 }
8532 return 0;
8533}
8534
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008535static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8536 v_U8_t *genie, v_U8_t *total_ielen)
8537{
8538 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8539 int left = pBeacon->tail_len;
8540 v_U8_t *ptr = pBeacon->tail;
8541 v_U8_t elem_id, elem_len;
8542 v_U16_t ielen = 0;
8543
8544 if ( NULL == ptr || 0 == left )
8545 return;
8546
8547 while (left >= 2)
8548 {
8549 elem_id = ptr[0];
8550 elem_len = ptr[1];
8551 left -= 2;
8552 if (elem_len > left)
8553 {
8554 hddLog( VOS_TRACE_LEVEL_ERROR,
8555 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8556 elem_id, elem_len, left);
8557 return;
8558 }
8559 if (IE_EID_VENDOR == elem_id)
8560 {
8561 /* skipping the VSIE's which we don't want to include or
8562 * it will be included by existing code
8563 */
8564 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8565#ifdef WLAN_FEATURE_WFD
8566 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8567#endif
8568 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8569 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8570 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8571 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8572 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8573 {
8574 ielen = ptr[1] + 2;
8575 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8576 {
8577 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8578 *total_ielen += ielen;
8579 }
8580 else
8581 {
8582 hddLog( VOS_TRACE_LEVEL_ERROR,
8583 "IE Length is too big "
8584 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8585 elem_id, elem_len, *total_ielen);
8586 }
8587 }
8588 }
8589
8590 left -= elem_len;
8591 ptr += (elem_len + 2);
8592 }
8593 return;
8594}
8595
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008596#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008597static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8598 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008599#else
8600static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8601 struct cfg80211_beacon_data *params)
8602#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008603{
8604 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308605 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008606 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008607 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008608
8609 genie = vos_mem_malloc(MAX_GENIE_LEN);
8610
8611 if(genie == NULL) {
8612
8613 return -ENOMEM;
8614 }
8615
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308616 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8617 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008618 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308619 hddLog(LOGE,
8620 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308621 ret = -EINVAL;
8622 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008623 }
8624
8625#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308626 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8627 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8628 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308629 hddLog(LOGE,
8630 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308631 ret = -EINVAL;
8632 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008633 }
8634#endif
8635
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308636 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8637 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008638 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308639 hddLog(LOGE,
8640 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308641 ret = -EINVAL;
8642 goto done;
8643 }
8644
8645 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8646 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008647 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008648 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008649
8650 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8651 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8652 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8653 {
8654 hddLog(LOGE,
8655 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008656 ret = -EINVAL;
8657 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008658 }
8659
8660 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8661 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8662 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8663 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8664 ==eHAL_STATUS_FAILURE)
8665 {
8666 hddLog(LOGE,
8667 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008668 ret = -EINVAL;
8669 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008670 }
8671
8672 // Added for ProResp IE
8673 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
8674 {
8675 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
8676 u8 probe_rsp_ie_len[3] = {0};
8677 u8 counter = 0;
8678 /* Check Probe Resp Length if it is greater then 255 then Store
8679 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8680 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8681 Store More then 255 bytes into One Variable.
8682 */
8683 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8684 {
8685 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8686 {
8687 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8688 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8689 }
8690 else
8691 {
8692 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8693 rem_probe_resp_ie_len = 0;
8694 }
8695 }
8696
8697 rem_probe_resp_ie_len = 0;
8698
8699 if (probe_rsp_ie_len[0] > 0)
8700 {
8701 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8702 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
8703 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8704 probe_rsp_ie_len[0], NULL,
8705 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8706 {
8707 hddLog(LOGE,
8708 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008709 ret = -EINVAL;
8710 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008711 }
8712 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8713 }
8714
8715 if (probe_rsp_ie_len[1] > 0)
8716 {
8717 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8718 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
8719 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8720 probe_rsp_ie_len[1], NULL,
8721 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8722 {
8723 hddLog(LOGE,
8724 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008725 ret = -EINVAL;
8726 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008727 }
8728 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8729 }
8730
8731 if (probe_rsp_ie_len[2] > 0)
8732 {
8733 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8734 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
8735 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8736 probe_rsp_ie_len[2], NULL,
8737 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8738 {
8739 hddLog(LOGE,
8740 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008741 ret = -EINVAL;
8742 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008743 }
8744 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8745 }
8746
8747 if (probe_rsp_ie_len[1] == 0 )
8748 {
8749 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8750 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8751 eANI_BOOLEAN_FALSE) )
8752 {
8753 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008754 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008755 }
8756 }
8757
8758 if (probe_rsp_ie_len[2] == 0 )
8759 {
8760 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8761 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8762 eANI_BOOLEAN_FALSE) )
8763 {
8764 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008765 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008766 }
8767 }
8768
8769 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8770 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8771 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8772 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8773 == eHAL_STATUS_FAILURE)
8774 {
8775 hddLog(LOGE,
8776 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008777 ret = -EINVAL;
8778 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008779 }
8780 }
8781 else
8782 {
8783 // Reset WNI_CFG_PROBE_RSP Flags
8784 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8785
8786 hddLog(VOS_TRACE_LEVEL_INFO,
8787 "%s: No Probe Response IE received in set beacon",
8788 __func__);
8789 }
8790
8791 // Added for AssocResp IE
8792 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
8793 {
8794 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8795 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
8796 params->assocresp_ies_len, NULL,
8797 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8798 {
8799 hddLog(LOGE,
8800 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008801 ret = -EINVAL;
8802 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008803 }
8804
8805 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8806 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8807 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8808 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8809 == eHAL_STATUS_FAILURE)
8810 {
8811 hddLog(LOGE,
8812 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008813 ret = -EINVAL;
8814 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008815 }
8816 }
8817 else
8818 {
8819 hddLog(VOS_TRACE_LEVEL_INFO,
8820 "%s: No Assoc Response IE received in set beacon",
8821 __func__);
8822
8823 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8824 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8825 eANI_BOOLEAN_FALSE) )
8826 {
8827 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008828 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008829 }
8830 }
8831
Jeff Johnsone7245742012-09-05 17:12:55 -07008832done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008833 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308834 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008835}
Jeff Johnson295189b2012-06-20 16:38:30 -07008836
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308837/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008838 * FUNCTION: wlan_hdd_validate_operation_channel
8839 * called by wlan_hdd_cfg80211_start_bss() and
8840 * wlan_hdd_cfg80211_set_channel()
8841 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308842 * channel list.
8843 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008844VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008845{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308846
Jeff Johnson295189b2012-06-20 16:38:30 -07008847 v_U32_t num_ch = 0;
8848 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8849 u32 indx = 0;
8850 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308851 v_U8_t fValidChannel = FALSE, count = 0;
8852 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308853
Jeff Johnson295189b2012-06-20 16:38:30 -07008854 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8855
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308856 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008857 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308858 /* Validate the channel */
8859 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008860 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308861 if ( channel == rfChannels[count].channelNum )
8862 {
8863 fValidChannel = TRUE;
8864 break;
8865 }
8866 }
8867 if (fValidChannel != TRUE)
8868 {
8869 hddLog(VOS_TRACE_LEVEL_ERROR,
8870 "%s: Invalid Channel [%d]", __func__, channel);
8871 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008872 }
8873 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308874 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008875 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308876 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8877 valid_ch, &num_ch))
8878 {
8879 hddLog(VOS_TRACE_LEVEL_ERROR,
8880 "%s: failed to get valid channel list", __func__);
8881 return VOS_STATUS_E_FAILURE;
8882 }
8883 for (indx = 0; indx < num_ch; indx++)
8884 {
8885 if (channel == valid_ch[indx])
8886 {
8887 break;
8888 }
8889 }
8890
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308891 if (indx >= num_ch)
8892 {
8893 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8894 {
8895 eCsrBand band;
8896 unsigned int freq;
8897
8898 sme_GetFreqBand(hHal, &band);
8899
8900 if (eCSR_BAND_5G == band)
8901 {
8902#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8903 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8904 {
8905 freq = ieee80211_channel_to_frequency(channel,
8906 IEEE80211_BAND_2GHZ);
8907 }
8908 else
8909 {
8910 freq = ieee80211_channel_to_frequency(channel,
8911 IEEE80211_BAND_5GHZ);
8912 }
8913#else
8914 freq = ieee80211_channel_to_frequency(channel);
8915#endif
8916 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
8917 return VOS_STATUS_SUCCESS;
8918 }
8919 }
8920
8921 hddLog(VOS_TRACE_LEVEL_ERROR,
8922 "%s: Invalid Channel [%d]", __func__, channel);
8923 return VOS_STATUS_E_FAILURE;
8924 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008925 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308926
Jeff Johnson295189b2012-06-20 16:38:30 -07008927 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308928
Jeff Johnson295189b2012-06-20 16:38:30 -07008929}
8930
Viral Modi3a32cc52013-02-08 11:14:52 -08008931/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308932 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08008933 * This function is used to set the channel number
8934 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308935static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08008936 struct ieee80211_channel *chan,
8937 enum nl80211_channel_type channel_type
8938 )
8939{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308940 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08008941 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07008942 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08008943 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308944 hdd_context_t *pHddCtx;
8945 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008946
8947 ENTER();
8948
8949 if( NULL == dev )
8950 {
8951 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008952 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08008953 return -ENODEV;
8954 }
8955 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308956
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308957 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8958 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
8959 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08008960 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308961 "%s: device_mode = %s (%d) freq = %d", __func__,
8962 hdd_device_modetoString(pAdapter->device_mode),
8963 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308964
8965 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8966 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308967 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08008968 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308969 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008970 }
8971
8972 /*
8973 * Do freq to chan conversion
8974 * TODO: for 11a
8975 */
8976
8977 channel = ieee80211_frequency_to_channel(freq);
8978
8979 /* Check freq range */
8980 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
8981 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
8982 {
8983 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008984 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08008985 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
8986 WNI_CFG_CURRENT_CHANNEL_STAMAX);
8987 return -EINVAL;
8988 }
8989
8990 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8991
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05308992 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
8993 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08008994 {
8995 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
8996 {
8997 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008998 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08008999 return -EINVAL;
9000 }
9001 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9002 "%s: set channel to [%d] for device mode =%d",
9003 __func__, channel,pAdapter->device_mode);
9004 }
9005 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009006 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009007 )
9008 {
9009 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9010 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9011 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9012
9013 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9014 {
9015 /* Link is up then return cant set channel*/
9016 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009017 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009018 return -EINVAL;
9019 }
9020
9021 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9022 pHddStaCtx->conn_info.operationChannel = channel;
9023 pRoamProfile->ChannelInfo.ChannelList =
9024 &pHddStaCtx->conn_info.operationChannel;
9025 }
9026 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009027 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009028 )
9029 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309030 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9031 {
9032 if(VOS_STATUS_SUCCESS !=
9033 wlan_hdd_validate_operation_channel(pAdapter,channel))
9034 {
9035 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009036 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309037 return -EINVAL;
9038 }
9039 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9040 }
9041 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009042 {
9043 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9044
9045 /* If auto channel selection is configured as enable/ 1 then ignore
9046 channel set by supplicant
9047 */
9048 if ( cfg_param->apAutoChannelSelection )
9049 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309050 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9051 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009052 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309053 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9054 __func__, hdd_device_modetoString(pAdapter->device_mode),
9055 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009056 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309057 else
9058 {
9059 if(VOS_STATUS_SUCCESS !=
9060 wlan_hdd_validate_operation_channel(pAdapter,channel))
9061 {
9062 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009063 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309064 return -EINVAL;
9065 }
9066 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9067 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009068 }
9069 }
9070 else
9071 {
9072 hddLog(VOS_TRACE_LEVEL_FATAL,
9073 "%s: Invalid device mode failed to set valid channel", __func__);
9074 return -EINVAL;
9075 }
9076 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309077 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009078}
9079
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309080static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9081 struct net_device *dev,
9082 struct ieee80211_channel *chan,
9083 enum nl80211_channel_type channel_type
9084 )
9085{
9086 int ret;
9087
9088 vos_ssr_protect(__func__);
9089 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9090 vos_ssr_unprotect(__func__);
9091
9092 return ret;
9093}
9094
Jeff Johnson295189b2012-06-20 16:38:30 -07009095#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9096static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9097 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009098#else
9099static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9100 struct cfg80211_beacon_data *params,
9101 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309102 enum nl80211_hidden_ssid hidden_ssid,
9103 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009104#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009105{
9106 tsap_Config_t *pConfig;
9107 beacon_data_t *pBeacon = NULL;
9108 struct ieee80211_mgmt *pMgmt_frame;
9109 v_U8_t *pIe=NULL;
9110 v_U16_t capab_info;
9111 eCsrAuthType RSNAuthType;
9112 eCsrEncryptionType RSNEncryptType;
9113 eCsrEncryptionType mcRSNEncryptType;
9114 int status = VOS_STATUS_SUCCESS;
9115 tpWLAN_SAPEventCB pSapEventCallback;
9116 hdd_hostapd_state_t *pHostapdState;
9117 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
9118 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309119 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009120 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309121 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009122 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009123 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309124 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009125 v_BOOL_t MFPCapable = VOS_FALSE;
9126 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309127 v_BOOL_t sapEnable11AC =
9128 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07009129 ENTER();
9130
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309131 iniConfig = pHddCtx->cfg_ini;
9132
Jeff Johnson295189b2012-06-20 16:38:30 -07009133 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9134
9135 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9136
9137 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9138
9139 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9140
9141 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9142
9143 //channel is already set in the set_channel Call back
9144 //pConfig->channel = pCommitConfig->channel;
9145
9146 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309147 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009148 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9149
9150 pConfig->dtim_period = pBeacon->dtim_period;
9151
Arif Hussain6d2a3322013-11-17 19:50:10 -08009152 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009153 pConfig->dtim_period);
9154
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009155 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009156 {
9157 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009158 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309159 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9160 {
9161 tANI_BOOLEAN restartNeeded;
9162 pConfig->ieee80211d = 1;
9163 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9164 sme_setRegInfo(hHal, pConfig->countryCode);
9165 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9166 }
9167 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009168 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009169 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009170 pConfig->ieee80211d = 1;
9171 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9172 sme_setRegInfo(hHal, pConfig->countryCode);
9173 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009174 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009175 else
9176 {
9177 pConfig->ieee80211d = 0;
9178 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309179 /*
9180 * If auto channel is configured i.e. channel is 0,
9181 * so skip channel validation.
9182 */
9183 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9184 {
9185 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9186 {
9187 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009188 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309189 return -EINVAL;
9190 }
9191 }
9192 else
9193 {
9194 if(1 != pHddCtx->is_dynamic_channel_range_set)
9195 {
9196 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9197 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9198 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9199 }
9200 pHddCtx->is_dynamic_channel_range_set = 0;
9201 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009202 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009203 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009204 {
9205 pConfig->ieee80211d = 0;
9206 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309207
9208#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9209 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9210 pConfig->authType = eSAP_OPEN_SYSTEM;
9211 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9212 pConfig->authType = eSAP_SHARED_KEY;
9213 else
9214 pConfig->authType = eSAP_AUTO_SWITCH;
9215#else
9216 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9217 pConfig->authType = eSAP_OPEN_SYSTEM;
9218 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9219 pConfig->authType = eSAP_SHARED_KEY;
9220 else
9221 pConfig->authType = eSAP_AUTO_SWITCH;
9222#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009223
9224 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309225
9226 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009227 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
9228
9229 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9230
9231 /*Set wps station to configured*/
9232 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9233
9234 if(pIe)
9235 {
9236 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9237 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009238 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009239 return -EINVAL;
9240 }
9241 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9242 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009243 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009244 /* Check 15 bit of WPS IE as it contain information for wps state
9245 * WPS state
9246 */
9247 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9248 {
9249 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9250 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9251 {
9252 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9253 }
9254 }
9255 }
9256 else
9257 {
9258 pConfig->wps_state = SAP_WPS_DISABLED;
9259 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309260 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009261
c_hpothufe599e92014-06-16 11:38:55 +05309262 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9263 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9264 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9265 eCSR_ENCRYPT_TYPE_NONE;
9266
Jeff Johnson295189b2012-06-20 16:38:30 -07009267 pConfig->RSNWPAReqIELength = 0;
9268 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309269 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009270 WLAN_EID_RSN);
9271 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309272 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009273 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9274 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9275 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309276 /* The actual processing may eventually be more extensive than
9277 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009278 * by the app.
9279 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309280 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009281 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9282 &RSNEncryptType,
9283 &mcRSNEncryptType,
9284 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009285 &MFPCapable,
9286 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009287 pConfig->pRSNWPAReqIE[1]+2,
9288 pConfig->pRSNWPAReqIE );
9289
9290 if( VOS_STATUS_SUCCESS == status )
9291 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309292 /* Now copy over all the security attributes you have
9293 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009294 * */
9295 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9296 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9297 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9298 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309299 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009300 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009301 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9302 }
9303 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309304
Jeff Johnson295189b2012-06-20 16:38:30 -07009305 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9306 pBeacon->tail, pBeacon->tail_len);
9307
9308 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9309 {
9310 if (pConfig->pRSNWPAReqIE)
9311 {
9312 /*Mixed mode WPA/WPA2*/
9313 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
9314 pConfig->RSNWPAReqIELength += pIe[1] + 2;
9315 }
9316 else
9317 {
9318 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9319 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9320 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309321 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009322 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9323 &RSNEncryptType,
9324 &mcRSNEncryptType,
9325 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009326 &MFPCapable,
9327 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009328 pConfig->pRSNWPAReqIE[1]+2,
9329 pConfig->pRSNWPAReqIE );
9330
9331 if( VOS_STATUS_SUCCESS == status )
9332 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309333 /* Now copy over all the security attributes you have
9334 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009335 * */
9336 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9337 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9338 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9339 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309340 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009341 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009342 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9343 }
9344 }
9345 }
9346
Jeff Johnson4416a782013-03-25 14:17:50 -07009347 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
9348 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9349 return -EINVAL;
9350 }
9351
Jeff Johnson295189b2012-06-20 16:38:30 -07009352 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9353
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009354#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009355 if (params->ssid != NULL)
9356 {
9357 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9358 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9359 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9360 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9361 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009362#else
9363 if (ssid != NULL)
9364 {
9365 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9366 pConfig->SSIDinfo.ssid.length = ssid_len;
9367 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9368 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9369 }
9370#endif
9371
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309372 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009373 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309374
Jeff Johnson295189b2012-06-20 16:38:30 -07009375 /* default value */
9376 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9377 pConfig->num_accept_mac = 0;
9378 pConfig->num_deny_mac = 0;
9379
9380 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9381 pBeacon->tail, pBeacon->tail_len);
9382
9383 /* pIe for black list is following form:
9384 type : 1 byte
9385 length : 1 byte
9386 OUI : 4 bytes
9387 acl type : 1 byte
9388 no of mac addr in black list: 1 byte
9389 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309390 */
9391 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 {
9393 pConfig->SapMacaddr_acl = pIe[6];
9394 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009395 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009396 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309397 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9398 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009399 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9400 for (i = 0; i < pConfig->num_deny_mac; i++)
9401 {
9402 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9403 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309404 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009405 }
9406 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9407 pBeacon->tail, pBeacon->tail_len);
9408
9409 /* pIe for white list is following form:
9410 type : 1 byte
9411 length : 1 byte
9412 OUI : 4 bytes
9413 acl type : 1 byte
9414 no of mac addr in white list: 1 byte
9415 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309416 */
9417 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009418 {
9419 pConfig->SapMacaddr_acl = pIe[6];
9420 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009421 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009422 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309423 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9424 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009425 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9426 for (i = 0; i < pConfig->num_accept_mac; i++)
9427 {
9428 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9429 acl_entry++;
9430 }
9431 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309432
Jeff Johnson295189b2012-06-20 16:38:30 -07009433 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9434
Jeff Johnsone7245742012-09-05 17:12:55 -07009435#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009436 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309437 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9438 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309439 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9440 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009441 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9442 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309443 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9444 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009445 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309446 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009447 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309448 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009449
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309450 /* If ACS disable and selected channel <= 14
9451 * OR
9452 * ACS enabled and ACS operating band is choosen as 2.4
9453 * AND
9454 * VHT in 2.4G Disabled
9455 * THEN
9456 * Fallback to 11N mode
9457 */
9458 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9459 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309460 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309461 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009462 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309463 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9464 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009465 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9466 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009467 }
9468#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309469
Jeff Johnson295189b2012-06-20 16:38:30 -07009470 // ht_capab is not what the name conveys,this is used for protection bitmap
9471 pConfig->ht_capab =
9472 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9473
9474 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
9475 {
9476 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9477 return -EINVAL;
9478 }
9479
9480 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309481 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009482 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9483 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309484 pConfig->obssProtEnabled =
9485 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009486
Chet Lanctot8cecea22014-02-11 19:09:36 -08009487#ifdef WLAN_FEATURE_11W
9488 pConfig->mfpCapable = MFPCapable;
9489 pConfig->mfpRequired = MFPRequired;
9490 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9491 pConfig->mfpCapable, pConfig->mfpRequired);
9492#endif
9493
Arif Hussain6d2a3322013-11-17 19:50:10 -08009494 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009495 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009496 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9497 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9498 (int)pConfig->channel);
9499 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9500 pConfig->SapHw_mode, pConfig->privacy,
9501 pConfig->authType);
9502 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9503 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9504 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9505 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009506
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309507 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009508 {
9509 //Bss already started. just return.
9510 //TODO Probably it should update some beacon params.
9511 hddLog( LOGE, "Bss Already started...Ignore the request");
9512 EXIT();
9513 return 0;
9514 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309515
Agarwal Ashish51325b52014-06-16 16:50:49 +05309516 if (vos_max_concurrent_connections_reached()) {
9517 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9518 return -EINVAL;
9519 }
9520
Jeff Johnson295189b2012-06-20 16:38:30 -07009521 pConfig->persona = pHostapdAdapter->device_mode;
9522
Peng Xu2446a892014-09-05 17:21:18 +05309523 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9524 if ( NULL != psmeConfig)
9525 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309526 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309527 sme_GetConfigParam(hHal, psmeConfig);
9528 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309529#ifdef WLAN_FEATURE_AP_HT40_24G
9530 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9531 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9532 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9533 {
9534 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9535 sme_UpdateConfig (hHal, psmeConfig);
9536 }
9537#endif
Peng Xu2446a892014-09-05 17:21:18 +05309538 vos_mem_free(psmeConfig);
9539 }
Peng Xuafc34e32014-09-25 13:23:55 +05309540 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309541
Jeff Johnson295189b2012-06-20 16:38:30 -07009542 pSapEventCallback = hdd_hostapd_SAPEventCB;
9543 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9544 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9545 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009546 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009547 return -EINVAL;
9548 }
9549
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309550 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009551 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9552
9553 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309554
Jeff Johnson295189b2012-06-20 16:38:30 -07009555 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309556 {
9557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009558 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009559 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009560 VOS_ASSERT(0);
9561 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309562
Jeff Johnson295189b2012-06-20 16:38:30 -07009563 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309564 /* Initialize WMM configuation */
9565 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309566 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009567
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009568#ifdef WLAN_FEATURE_P2P_DEBUG
9569 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9570 {
9571 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9572 {
9573 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9574 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009575 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009576 }
9577 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9578 {
9579 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9580 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009581 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009582 }
9583 }
9584#endif
9585
Jeff Johnson295189b2012-06-20 16:38:30 -07009586 pHostapdState->bCommit = TRUE;
9587 EXIT();
9588
9589 return 0;
9590}
9591
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009592#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309593static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309594 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009595 struct beacon_parameters *params)
9596{
9597 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309598 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309599 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009600
9601 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309602
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309603 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9604 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9605 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309606 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9607 hdd_device_modetoString(pAdapter->device_mode),
9608 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009609
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309610 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9611 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309612 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009613 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309614 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009615 }
9616
Agarwal Ashish51325b52014-06-16 16:50:49 +05309617 if (vos_max_concurrent_connections_reached()) {
9618 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9619 return -EINVAL;
9620 }
9621
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309622 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009624 )
9625 {
9626 beacon_data_t *old,*new;
9627
9628 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309629
Jeff Johnson295189b2012-06-20 16:38:30 -07009630 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309631 {
9632 hddLog(VOS_TRACE_LEVEL_WARN,
9633 FL("already beacon info added to session(%d)"),
9634 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009635 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309636 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009637
9638 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9639
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309640 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009641 {
9642 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009643 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009644 return -EINVAL;
9645 }
9646
9647 pAdapter->sessionCtx.ap.beacon = new;
9648
9649 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9650 }
9651
9652 EXIT();
9653 return status;
9654}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309655
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309656static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9657 struct net_device *dev,
9658 struct beacon_parameters *params)
9659{
9660 int ret;
9661
9662 vos_ssr_protect(__func__);
9663 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
9664 vos_ssr_unprotect(__func__);
9665
9666 return ret;
9667}
9668
9669static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009670 struct net_device *dev,
9671 struct beacon_parameters *params)
9672{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309673 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309674 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9675 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309676 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009677
9678 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309679
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309680 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9681 TRACE_CODE_HDD_CFG80211_SET_BEACON,
9682 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
9683 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9684 __func__, hdd_device_modetoString(pAdapter->device_mode),
9685 pAdapter->device_mode);
9686
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309687 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9688 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309689 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009690 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309691 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009692 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309693
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309694 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009695 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309696 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009697 {
9698 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309699
Jeff Johnson295189b2012-06-20 16:38:30 -07009700 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309701
Jeff Johnson295189b2012-06-20 16:38:30 -07009702 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309703 {
9704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9705 FL("session(%d) old and new heads points to NULL"),
9706 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009707 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309708 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009709
9710 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9711
9712 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309713 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009714 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009715 return -EINVAL;
9716 }
9717
9718 pAdapter->sessionCtx.ap.beacon = new;
9719
9720 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9721 }
9722
9723 EXIT();
9724 return status;
9725}
9726
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309727static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
9728 struct net_device *dev,
9729 struct beacon_parameters *params)
9730{
9731 int ret;
9732
9733 vos_ssr_protect(__func__);
9734 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
9735 vos_ssr_unprotect(__func__);
9736
9737 return ret;
9738}
9739
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009740#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9741
9742#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309743static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009744 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009745#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309746static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009747 struct net_device *dev)
9748#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009749{
9750 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07009751 hdd_context_t *pHddCtx = NULL;
9752 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309753 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309754 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009755
9756 ENTER();
9757
9758 if (NULL == pAdapter)
9759 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009761 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009762 return -ENODEV;
9763 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009764
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309765 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9766 TRACE_CODE_HDD_CFG80211_STOP_AP,
9767 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309768 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9769 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309770 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009771 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309772 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07009773 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009774
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009775 pScanInfo = &pHddCtx->scan_info;
9776
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309777 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9778 __func__, hdd_device_modetoString(pAdapter->device_mode),
9779 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009780
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309781 ret = wlan_hdd_scan_abort(pAdapter);
9782
Girish Gowli4bf7a632014-06-12 13:42:11 +05309783 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07009784 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9786 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309787
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309788 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07009789 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9791 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08009792
Jeff Johnsone7245742012-09-05 17:12:55 -07009793 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309794 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07009795 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309796 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009797 }
9798
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05309799 /* Delete all associated STAs before stopping AP/P2P GO */
9800 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05309801 hdd_hostapd_stop(dev);
9802
Jeff Johnson295189b2012-06-20 16:38:30 -07009803 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009804 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009805 )
9806 {
9807 beacon_data_t *old;
9808
9809 old = pAdapter->sessionCtx.ap.beacon;
9810
9811 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309812 {
9813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9814 FL("session(%d) beacon data points to NULL"),
9815 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009816 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309817 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009818
Jeff Johnson295189b2012-06-20 16:38:30 -07009819 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009820
9821 mutex_lock(&pHddCtx->sap_lock);
9822 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9823 {
Jeff Johnson4416a782013-03-25 14:17:50 -07009824 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009825 {
9826 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9827
9828 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9829
9830 if (!VOS_IS_STATUS_SUCCESS(status))
9831 {
9832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009833 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009834 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309835 }
9836 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009837 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309838 /* BSS stopped, clear the active sessions for this device mode */
9839 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009840 }
9841 mutex_unlock(&pHddCtx->sap_lock);
9842
9843 if(status != VOS_STATUS_SUCCESS)
9844 {
9845 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009846 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 return -EINVAL;
9848 }
9849
Jeff Johnson4416a782013-03-25 14:17:50 -07009850 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009851 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
9852 ==eHAL_STATUS_FAILURE)
9853 {
9854 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009855 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009856 }
9857
Jeff Johnson4416a782013-03-25 14:17:50 -07009858 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009859 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9860 eANI_BOOLEAN_FALSE) )
9861 {
9862 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009863 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009864 }
9865
9866 // Reset WNI_CFG_PROBE_RSP Flags
9867 wlan_hdd_reset_prob_rspies(pAdapter);
9868
9869 pAdapter->sessionCtx.ap.beacon = NULL;
9870 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009871#ifdef WLAN_FEATURE_P2P_DEBUG
9872 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
9873 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
9874 {
9875 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
9876 "GO got removed");
9877 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
9878 }
9879#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009880 }
9881 EXIT();
9882 return status;
9883}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009884
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309885#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9886static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
9887 struct net_device *dev)
9888{
9889 int ret;
9890
9891 vos_ssr_protect(__func__);
9892 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
9893 vos_ssr_unprotect(__func__);
9894
9895 return ret;
9896}
9897#else
9898static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
9899 struct net_device *dev)
9900{
9901 int ret;
9902
9903 vos_ssr_protect(__func__);
9904 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
9905 vos_ssr_unprotect(__func__);
9906
9907 return ret;
9908}
9909#endif
9910
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009911#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
9912
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309913static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309914 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009915 struct cfg80211_ap_settings *params)
9916{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309917 hdd_adapter_t *pAdapter;
9918 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309919 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009920
9921 ENTER();
9922
Girish Gowlib143d7a2015-02-18 19:39:55 +05309923 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009924 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05309926 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309927 return -ENODEV;
9928 }
9929
9930 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9931 if (NULL == pAdapter)
9932 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309933 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309934 "%s: HDD adapter is Null", __func__);
9935 return -ENODEV;
9936 }
9937
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309938 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9939 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
9940 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309941 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9942 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309944 "%s: HDD adapter magic is invalid", __func__);
9945 return -ENODEV;
9946 }
9947
9948 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309949 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309950 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309951 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309952 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309953 }
9954
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309955 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
9956 __func__, hdd_device_modetoString(pAdapter->device_mode),
9957 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309958
9959 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009960 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009961 )
9962 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309963 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009964
9965 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309966
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009967 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309968 {
9969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9970 FL("already beacon info added to session(%d)"),
9971 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009972 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309973 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009974
Girish Gowlib143d7a2015-02-18 19:39:55 +05309975#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9976 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
9977 &new,
9978 &params->beacon);
9979#else
9980 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
9981 &new,
9982 &params->beacon,
9983 params->dtim_period);
9984#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009985
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309986 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009987 {
9988 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309989 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009990 return -EINVAL;
9991 }
9992 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08009993#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07009994 wlan_hdd_cfg80211_set_channel(wiphy, dev,
9995#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
9996 params->channel, params->channel_type);
9997#else
9998 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
9999#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010000#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010001 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010002 params->ssid_len, params->hidden_ssid,
10003 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010004 }
10005
10006 EXIT();
10007 return status;
10008}
10009
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010010static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10011 struct net_device *dev,
10012 struct cfg80211_ap_settings *params)
10013{
10014 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010015
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010016 vos_ssr_protect(__func__);
10017 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10018 vos_ssr_unprotect(__func__);
10019
10020 return ret;
10021}
10022
10023static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010024 struct net_device *dev,
10025 struct cfg80211_beacon_data *params)
10026{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010027 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010028 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010029 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010030
10031 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010032
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010033 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10034 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10035 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010036 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010037 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010038
10039 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10040 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010041 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010042 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010043 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010044 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010045
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010046 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010047 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010048 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010049 {
10050 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010051
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010052 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010053
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010054 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010055 {
10056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10057 FL("session(%d) beacon data points to NULL"),
10058 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010059 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010060 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010061
10062 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10063
10064 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010065 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010066 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010067 return -EINVAL;
10068 }
10069
10070 pAdapter->sessionCtx.ap.beacon = new;
10071
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010072 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10073 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010074 }
10075
10076 EXIT();
10077 return status;
10078}
10079
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010080static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10081 struct net_device *dev,
10082 struct cfg80211_beacon_data *params)
10083{
10084 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010085
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010086 vos_ssr_protect(__func__);
10087 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10088 vos_ssr_unprotect(__func__);
10089
10090 return ret;
10091}
10092
10093#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010094
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010095static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010096 struct net_device *dev,
10097 struct bss_parameters *params)
10098{
10099 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010100 hdd_context_t *pHddCtx;
10101 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010102
10103 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010104
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010105 if (NULL == pAdapter)
10106 {
10107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10108 "%s: HDD adapter is Null", __func__);
10109 return -ENODEV;
10110 }
10111 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010112 ret = wlan_hdd_validate_context(pHddCtx);
10113 if (0 != ret)
10114 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010115 return ret;
10116 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010117 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10118 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10119 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010120 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10121 __func__, hdd_device_modetoString(pAdapter->device_mode),
10122 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010123
10124 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010125 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010126 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010127 {
10128 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10129 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010130 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010131 {
10132 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010133 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010134 }
10135
10136 EXIT();
10137 return 0;
10138}
10139
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010140static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10141 struct net_device *dev,
10142 struct bss_parameters *params)
10143{
10144 int ret;
10145
10146 vos_ssr_protect(__func__);
10147 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10148 vos_ssr_unprotect(__func__);
10149
10150 return ret;
10151}
Kiet Lam10841362013-11-01 11:36:50 +053010152/* FUNCTION: wlan_hdd_change_country_code_cd
10153* to wait for contry code completion
10154*/
10155void* wlan_hdd_change_country_code_cb(void *pAdapter)
10156{
10157 hdd_adapter_t *call_back_pAdapter = pAdapter;
10158 complete(&call_back_pAdapter->change_country_code);
10159 return NULL;
10160}
10161
Jeff Johnson295189b2012-06-20 16:38:30 -070010162/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010163 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010164 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10165 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010166int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010167 struct net_device *ndev,
10168 enum nl80211_iftype type,
10169 u32 *flags,
10170 struct vif_params *params
10171 )
10172{
10173 struct wireless_dev *wdev;
10174 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010175 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010176 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010177 tCsrRoamProfile *pRoamProfile = NULL;
10178 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010179 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010180 eMib_dot11DesiredBssType connectedBssType;
10181 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010182 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010183
10184 ENTER();
10185
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010186 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010187 {
10188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10189 "%s: Adapter context is null", __func__);
10190 return VOS_STATUS_E_FAILURE;
10191 }
10192
10193 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10194 if (!pHddCtx)
10195 {
10196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10197 "%s: HDD context is null", __func__);
10198 return VOS_STATUS_E_FAILURE;
10199 }
10200
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010201 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10202 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10203 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010204 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010205 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010206 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010207 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010208 }
10209
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010210 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10211 __func__, hdd_device_modetoString(pAdapter->device_mode),
10212 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010213
Agarwal Ashish51325b52014-06-16 16:50:49 +053010214 if (vos_max_concurrent_connections_reached()) {
10215 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10216 return -EINVAL;
10217 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010218 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010219 wdev = ndev->ieee80211_ptr;
10220
10221#ifdef WLAN_BTAMP_FEATURE
10222 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10223 (NL80211_IFTYPE_ADHOC == type)||
10224 (NL80211_IFTYPE_AP == type)||
10225 (NL80211_IFTYPE_P2P_GO == type))
10226 {
10227 pHddCtx->isAmpAllowed = VOS_FALSE;
10228 // stop AMP traffic
10229 status = WLANBAP_StopAmp();
10230 if(VOS_STATUS_SUCCESS != status )
10231 {
10232 pHddCtx->isAmpAllowed = VOS_TRUE;
10233 hddLog(VOS_TRACE_LEVEL_FATAL,
10234 "%s: Failed to stop AMP", __func__);
10235 return -EINVAL;
10236 }
10237 }
10238#endif //WLAN_BTAMP_FEATURE
10239 /* Reset the current device mode bit mask*/
10240 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10241
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010242 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10243 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10244 (type == NL80211_IFTYPE_P2P_GO)))
10245 {
10246 /* Notify Mode change in case of concurrency.
10247 * Below function invokes TDLS teardown Functionality Since TDLS is
10248 * not Supported in case of concurrency i.e Once P2P session
10249 * is detected disable offchannel and teardown TDLS links
10250 */
10251 hddLog(LOG1,
10252 FL("Device mode = %d Interface type = %d"),
10253 pAdapter->device_mode, type);
10254 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10255 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010256
Jeff Johnson295189b2012-06-20 16:38:30 -070010257 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010258 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010259 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010260 )
10261 {
10262 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010263 if (!pWextState)
10264 {
10265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10266 "%s: pWextState is null", __func__);
10267 return VOS_STATUS_E_FAILURE;
10268 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010269 pRoamProfile = &pWextState->roamProfile;
10270 LastBSSType = pRoamProfile->BSSType;
10271
10272 switch (type)
10273 {
10274 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010275 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010276 hddLog(VOS_TRACE_LEVEL_INFO,
10277 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10278 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010279#ifdef WLAN_FEATURE_11AC
10280 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10281 {
10282 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10283 }
10284#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010285 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010286 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010287 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010288 //Check for sub-string p2p to confirm its a p2p interface
10289 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010290 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010291#ifdef FEATURE_WLAN_TDLS
10292 mutex_lock(&pHddCtx->tdls_lock);
10293 wlan_hdd_tdls_exit(pAdapter, TRUE);
10294 mutex_unlock(&pHddCtx->tdls_lock);
10295#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010296 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10297 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10298 }
10299 else
10300 {
10301 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010302 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010303 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010304 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010305
Jeff Johnson295189b2012-06-20 16:38:30 -070010306 case NL80211_IFTYPE_ADHOC:
10307 hddLog(VOS_TRACE_LEVEL_INFO,
10308 "%s: setting interface Type to ADHOC", __func__);
10309 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10310 pRoamProfile->phyMode =
10311 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010312 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010313 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010314 hdd_set_ibss_ops( pAdapter );
10315 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010316
10317 status = hdd_sta_id_hash_attach(pAdapter);
10318 if (VOS_STATUS_SUCCESS != status) {
10319 hddLog(VOS_TRACE_LEVEL_ERROR,
10320 FL("Failed to initialize hash for IBSS"));
10321 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010322 break;
10323
10324 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010325 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010326 {
10327 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10328 "%s: setting interface Type to %s", __func__,
10329 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10330
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010331 //Cancel any remain on channel for GO mode
10332 if (NL80211_IFTYPE_P2P_GO == type)
10333 {
10334 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10335 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010336 if (NL80211_IFTYPE_AP == type)
10337 {
10338 /* As Loading WLAN Driver one interface being created for p2p device
10339 * address. This will take one HW STA and the max number of clients
10340 * that can connect to softAP will be reduced by one. so while changing
10341 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10342 * interface as it is not required in SoftAP mode.
10343 */
10344
10345 // Get P2P Adapter
10346 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10347
10348 if (pP2pAdapter)
10349 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010350 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010351 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010352 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10353 }
10354 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010355 //Disable IMPS & BMPS for SAP/GO
10356 if(VOS_STATUS_E_FAILURE ==
10357 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10358 {
10359 //Fail to Exit BMPS
10360 VOS_ASSERT(0);
10361 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010362
10363 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10364
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010365#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010366
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010367 /* A Mutex Lock is introduced while changing the mode to
10368 * protect the concurrent access for the Adapters by TDLS
10369 * module.
10370 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010371 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010372#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010373 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010374 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010375 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010376 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10377 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010378#ifdef FEATURE_WLAN_TDLS
10379 mutex_unlock(&pHddCtx->tdls_lock);
10380#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010381 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10382 (pConfig->apRandomBssidEnabled))
10383 {
10384 /* To meet Android requirements create a randomized
10385 MAC address of the form 02:1A:11:Fx:xx:xx */
10386 get_random_bytes(&ndev->dev_addr[3], 3);
10387 ndev->dev_addr[0] = 0x02;
10388 ndev->dev_addr[1] = 0x1A;
10389 ndev->dev_addr[2] = 0x11;
10390 ndev->dev_addr[3] |= 0xF0;
10391 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10392 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010393 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10394 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010395 }
10396
Jeff Johnson295189b2012-06-20 16:38:30 -070010397 hdd_set_ap_ops( pAdapter->dev );
10398
Kiet Lam10841362013-11-01 11:36:50 +053010399 /* This is for only SAP mode where users can
10400 * control country through ini.
10401 * P2P GO follows station country code
10402 * acquired during the STA scanning. */
10403 if((NL80211_IFTYPE_AP == type) &&
10404 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10405 {
10406 int status = 0;
10407 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10408 "%s: setting country code from INI ", __func__);
10409 init_completion(&pAdapter->change_country_code);
10410 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10411 (void *)(tSmeChangeCountryCallback)
10412 wlan_hdd_change_country_code_cb,
10413 pConfig->apCntryCode, pAdapter,
10414 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010415 eSIR_FALSE,
10416 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010417 if (eHAL_STATUS_SUCCESS == status)
10418 {
10419 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010420 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010421 &pAdapter->change_country_code,
10422 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010423 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010424 {
10425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010426 FL("SME Timed out while setting country code %ld"),
10427 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010428
10429 if (pHddCtx->isLogpInProgress)
10430 {
10431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10432 "%s: LOGP in Progress. Ignore!!!", __func__);
10433 return -EAGAIN;
10434 }
Kiet Lam10841362013-11-01 11:36:50 +053010435 }
10436 }
10437 else
10438 {
10439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010440 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010441 return -EINVAL;
10442 }
10443 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010444 status = hdd_init_ap_mode(pAdapter);
10445 if(status != VOS_STATUS_SUCCESS)
10446 {
10447 hddLog(VOS_TRACE_LEVEL_FATAL,
10448 "%s: Error initializing the ap mode", __func__);
10449 return -EINVAL;
10450 }
10451 hdd_set_conparam(1);
10452
Nirav Shah7e3c8132015-06-22 23:51:42 +053010453 status = hdd_sta_id_hash_attach(pAdapter);
10454 if (VOS_STATUS_SUCCESS != status)
10455 {
10456 hddLog(VOS_TRACE_LEVEL_ERROR,
10457 FL("Failed to initialize hash for AP"));
10458 return -EINVAL;
10459 }
10460
Jeff Johnson295189b2012-06-20 16:38:30 -070010461 /*interface type changed update in wiphy structure*/
10462 if(wdev)
10463 {
10464 wdev->iftype = type;
10465 pHddCtx->change_iface = type;
10466 }
10467 else
10468 {
10469 hddLog(VOS_TRACE_LEVEL_ERROR,
10470 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10471 return -EINVAL;
10472 }
10473 goto done;
10474 }
10475
10476 default:
10477 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10478 __func__);
10479 return -EOPNOTSUPP;
10480 }
10481 }
10482 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010483 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010484 )
10485 {
10486 switch(type)
10487 {
10488 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010489 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010490 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010491
10492 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010493#ifdef FEATURE_WLAN_TDLS
10494
10495 /* A Mutex Lock is introduced while changing the mode to
10496 * protect the concurrent access for the Adapters by TDLS
10497 * module.
10498 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010499 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010500#endif
c_hpothu002231a2015-02-05 14:58:51 +053010501 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010502 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010503 //Check for sub-string p2p to confirm its a p2p interface
10504 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010505 {
10506 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10507 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10508 }
10509 else
10510 {
10511 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010512 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010513 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010514 hdd_set_conparam(0);
10515 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010516 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10517 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010518#ifdef FEATURE_WLAN_TDLS
10519 mutex_unlock(&pHddCtx->tdls_lock);
10520#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010521 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010522 if( VOS_STATUS_SUCCESS != status )
10523 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010524 /* In case of JB, for P2P-GO, only change interface will be called,
10525 * This is the right place to enable back bmps_imps()
10526 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010527 if (pHddCtx->hdd_wlan_suspended)
10528 {
10529 hdd_set_pwrparams(pHddCtx);
10530 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010531 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010532 goto done;
10533 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010535 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010536 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10537 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010538 goto done;
10539 default:
10540 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10541 __func__);
10542 return -EOPNOTSUPP;
10543
10544 }
10545
10546 }
10547 else
10548 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010549 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10550 __func__, hdd_device_modetoString(pAdapter->device_mode),
10551 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010552 return -EOPNOTSUPP;
10553 }
10554
10555
10556 if(pRoamProfile)
10557 {
10558 if ( LastBSSType != pRoamProfile->BSSType )
10559 {
10560 /*interface type changed update in wiphy structure*/
10561 wdev->iftype = type;
10562
10563 /*the BSS mode changed, We need to issue disconnect
10564 if connected or in IBSS disconnect state*/
10565 if ( hdd_connGetConnectedBssType(
10566 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10567 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10568 {
10569 /*need to issue a disconnect to CSR.*/
10570 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10571 if( eHAL_STATUS_SUCCESS ==
10572 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10573 pAdapter->sessionId,
10574 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10575 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010576 ret = wait_for_completion_interruptible_timeout(
10577 &pAdapter->disconnect_comp_var,
10578 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10579 if (ret <= 0)
10580 {
10581 hddLog(VOS_TRACE_LEVEL_ERROR,
10582 FL("wait on disconnect_comp_var failed %ld"), ret);
10583 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010584 }
10585 }
10586 }
10587 }
10588
10589done:
10590 /*set bitmask based on updated value*/
10591 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010592
10593 /* Only STA mode support TM now
10594 * all other mode, TM feature should be disabled */
10595 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10596 (~VOS_STA & pHddCtx->concurrency_mode) )
10597 {
10598 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10599 }
10600
Jeff Johnson295189b2012-06-20 16:38:30 -070010601#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010602 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010603 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010604 {
10605 //we are ok to do AMP
10606 pHddCtx->isAmpAllowed = VOS_TRUE;
10607 }
10608#endif //WLAN_BTAMP_FEATURE
10609 EXIT();
10610 return 0;
10611}
10612
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010613/*
10614 * FUNCTION: wlan_hdd_cfg80211_change_iface
10615 * wrapper function to protect the actual implementation from SSR.
10616 */
10617int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10618 struct net_device *ndev,
10619 enum nl80211_iftype type,
10620 u32 *flags,
10621 struct vif_params *params
10622 )
10623{
10624 int ret;
10625
10626 vos_ssr_protect(__func__);
10627 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10628 vos_ssr_unprotect(__func__);
10629
10630 return ret;
10631}
10632
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010633#ifdef FEATURE_WLAN_TDLS
10634static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010635 struct net_device *dev,
10636#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10637 const u8 *mac,
10638#else
10639 u8 *mac,
10640#endif
10641 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010642{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010643 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010644 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010645 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010646 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010647 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010648 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010649
10650 ENTER();
10651
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010652 if (!dev) {
10653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10654 return -EINVAL;
10655 }
10656
10657 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10658 if (!pAdapter) {
10659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
10660 return -EINVAL;
10661 }
10662
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010663 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010664 {
10665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10666 "Invalid arguments");
10667 return -EINVAL;
10668 }
Hoonki Lee27511902013-03-14 18:19:06 -070010669
10670 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
10671 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
10672 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070010674 "%s: TDLS mode is disabled OR not enabled in FW."
10675 MAC_ADDRESS_STR " Request declined.",
10676 __func__, MAC_ADDR_ARRAY(mac));
10677 return -ENOTSUPP;
10678 }
10679
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010680 if (pHddCtx->isLogpInProgress)
10681 {
10682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10683 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053010684 wlan_hdd_tdls_set_link_status(pAdapter,
10685 mac,
10686 eTDLS_LINK_IDLE,
10687 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010688 return -EBUSY;
10689 }
10690
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010691 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053010692 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010693
10694 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010696 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
10697 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010698 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010699 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010700 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010701
10702 /* in add station, we accept existing valid staId if there is */
10703 if ((0 == update) &&
10704 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
10705 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010706 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010708 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010709 " link_status %d. staId %d. add station ignored.",
10710 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010711 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010712 return 0;
10713 }
10714 /* in change station, we accept only when staId is valid */
10715 if ((1 == update) &&
10716 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
10717 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
10718 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010719 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010721 "%s: " MAC_ADDRESS_STR
10722 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010723 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
10724 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
10725 mutex_unlock(&pHddCtx->tdls_lock);
10726 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010727 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010728 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010729
10730 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053010731 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010732 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10734 "%s: " MAC_ADDRESS_STR
10735 " TDLS setup is ongoing. Request declined.",
10736 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070010737 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010738 }
10739
10740 /* first to check if we reached to maximum supported TDLS peer.
10741 TODO: for now, return -EPERM looks working fine,
10742 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010743 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
10744 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010745 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10747 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010748 " TDLS Max peer already connected. Request declined."
10749 " Num of peers (%d), Max allowed (%d).",
10750 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
10751 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010752 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010753 }
10754 else
10755 {
10756 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010757 mutex_lock(&pHddCtx->tdls_lock);
10758 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010759 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010760 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010761 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10763 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
10764 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010765 return -EPERM;
10766 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010767 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010768 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010769 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053010770 wlan_hdd_tdls_set_link_status(pAdapter,
10771 mac,
10772 eTDLS_LINK_CONNECTING,
10773 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010774
Jeff Johnsond75fe012013-04-06 10:53:06 -070010775 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010776 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010777 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010779 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010780 if(StaParams->htcap_present)
10781 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010783 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010785 "ht_capa->extended_capabilities: %0x",
10786 StaParams->HTCap.extendedHtCapInfo);
10787 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010789 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010791 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010792 if(StaParams->vhtcap_present)
10793 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010795 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
10796 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
10797 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
10798 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010799 {
10800 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010802 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010804 "[%d]: %x ", i, StaParams->supported_rates[i]);
10805 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070010806 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010807 else if ((1 == update) && (NULL == StaParams))
10808 {
10809 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10810 "%s : update is true, but staParams is NULL. Error!", __func__);
10811 return -EPERM;
10812 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010813
10814 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
10815
10816 if (!update)
10817 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010818 /*Before adding sta make sure that device exited from BMPS*/
10819 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
10820 {
10821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10822 "%s: Adding tdls peer sta. Disable BMPS", __func__);
10823 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10824 if (status != VOS_STATUS_SUCCESS) {
10825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
10826 }
10827 }
10828
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010829 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010830 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010831 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010832 hddLog(VOS_TRACE_LEVEL_ERROR,
10833 FL("Failed to add TDLS peer STA. Enable Bmps"));
10834 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010835 return -EPERM;
10836 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010837 }
10838 else
10839 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010840 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010841 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010842 if (ret != eHAL_STATUS_SUCCESS) {
10843 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
10844 return -EPERM;
10845 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010846 }
10847
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010848 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010849 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
10850
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010851 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010852 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010854 "%s: timeout waiting for tdls add station indication %ld",
10855 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010856 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010857 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010858
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010859 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
10860 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010862 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010863 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010864 }
10865
10866 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070010867
10868error:
Atul Mittal115287b2014-07-08 13:26:33 +053010869 wlan_hdd_tdls_set_link_status(pAdapter,
10870 mac,
10871 eTDLS_LINK_IDLE,
10872 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010873 return -EPERM;
10874
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010875}
10876#endif
10877
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010878static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010879 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010880#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10881 const u8 *mac,
10882#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010883 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010884#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010885 struct station_parameters *params)
10886{
10887 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010888 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010889 hdd_context_t *pHddCtx;
10890 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010891 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010892 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010893#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010894 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010895 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010896 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010897#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010898
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010899 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010900
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010901 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010902 if ((NULL == pAdapter))
10903 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010904 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010905 "invalid adapter ");
10906 return -EINVAL;
10907 }
10908
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010909 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10910 TRACE_CODE_HDD_CHANGE_STATION,
10911 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053010912 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010913
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010914 ret = wlan_hdd_validate_context(pHddCtx);
10915 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053010916 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010917 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010918 }
10919
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010920 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10921
10922 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010923 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10925 "invalid HDD station context");
10926 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010927 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010928 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
10929
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010930 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10931 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070010932 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010933 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070010934 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010935 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070010936 WLANTL_STA_AUTHENTICATED);
10937
Gopichand Nakkala29149562013-05-10 21:43:41 +053010938 if (status != VOS_STATUS_SUCCESS)
10939 {
10940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10941 "%s: Not able to change TL state to AUTHENTICATED", __func__);
10942 return -EINVAL;
10943 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010944 }
10945 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070010946 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
10947 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010948#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010949 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
10950 StaParams.capability = params->capability;
10951 StaParams.uapsd_queues = params->uapsd_queues;
10952 StaParams.max_sp = params->max_sp;
10953
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010954 /* Convert (first channel , number of channels) tuple to
10955 * the total list of channels. This goes with the assumption
10956 * that if the first channel is < 14, then the next channels
10957 * are an incremental of 1 else an incremental of 4 till the number
10958 * of channels.
10959 */
10960 if (0 != params->supported_channels_len) {
10961 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
10962 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
10963 {
10964 int wifi_chan_index;
10965 StaParams.supported_channels[j] = params->supported_channels[i];
10966 wifi_chan_index =
10967 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
10968 no_of_channels = params->supported_channels[i+1];
10969 for(k=1; k <= no_of_channels; k++)
10970 {
10971 StaParams.supported_channels[j+1] =
10972 StaParams.supported_channels[j] + wifi_chan_index;
10973 j+=1;
10974 }
10975 }
10976 StaParams.supported_channels_len = j;
10977 }
10978 vos_mem_copy(StaParams.supported_oper_classes,
10979 params->supported_oper_classes,
10980 params->supported_oper_classes_len);
10981 StaParams.supported_oper_classes_len =
10982 params->supported_oper_classes_len;
10983
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010984 if (0 != params->ext_capab_len)
10985 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
10986 sizeof(StaParams.extn_capability));
10987
10988 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070010989 {
10990 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010991 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070010992 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010993
10994 StaParams.supported_rates_len = params->supported_rates_len;
10995
10996 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
10997 * The supported_rates array , for all the structures propogating till Add Sta
10998 * to the firmware has to be modified , if the supplicant (ieee80211) is
10999 * modified to send more rates.
11000 */
11001
11002 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11003 */
11004 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11005 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11006
11007 if (0 != StaParams.supported_rates_len) {
11008 int i = 0;
11009 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11010 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011012 "Supported Rates with Length %d", StaParams.supported_rates_len);
11013 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011015 "[%d]: %0x", i, StaParams.supported_rates[i]);
11016 }
11017
11018 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011019 {
11020 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011021 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011022 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011023
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011024 if (0 != params->ext_capab_len ) {
11025 /*Define A Macro : TODO Sunil*/
11026 if ((1<<4) & StaParams.extn_capability[3]) {
11027 isBufSta = 1;
11028 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011029 /* TDLS Channel Switching Support */
11030 if ((1<<6) & StaParams.extn_capability[3]) {
11031 isOffChannelSupported = 1;
11032 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011033 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011034 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11035 &StaParams, isBufSta,
11036 isOffChannelSupported);
11037
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011038 if (VOS_STATUS_SUCCESS != status) {
11039 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11040 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11041 return -EINVAL;
11042 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011043 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11044
11045 if (VOS_STATUS_SUCCESS != status) {
11046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11047 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11048 return -EINVAL;
11049 }
11050 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011051#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011052 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011053 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011054 return status;
11055}
11056
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011057#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11058static int wlan_hdd_change_station(struct wiphy *wiphy,
11059 struct net_device *dev,
11060 const u8 *mac,
11061 struct station_parameters *params)
11062#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011063static int wlan_hdd_change_station(struct wiphy *wiphy,
11064 struct net_device *dev,
11065 u8 *mac,
11066 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011067#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011068{
11069 int ret;
11070
11071 vos_ssr_protect(__func__);
11072 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11073 vos_ssr_unprotect(__func__);
11074
11075 return ret;
11076}
11077
Jeff Johnson295189b2012-06-20 16:38:30 -070011078/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011079 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011080 * This function is used to initialize the key information
11081 */
11082#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011083static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011084 struct net_device *ndev,
11085 u8 key_index, bool pairwise,
11086 const u8 *mac_addr,
11087 struct key_params *params
11088 )
11089#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011090static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011091 struct net_device *ndev,
11092 u8 key_index, const u8 *mac_addr,
11093 struct key_params *params
11094 )
11095#endif
11096{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011097 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011098 tCsrRoamSetKey setKey;
11099 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011100 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011101 v_U32_t roamId= 0xFF;
11102 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011103 hdd_hostapd_state_t *pHostapdState;
11104 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011105 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011106 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011107
11108 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011109
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011110 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11111 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11112 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011113 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11114 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011115 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011116 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011117 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011118 }
11119
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011120 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11121 __func__, hdd_device_modetoString(pAdapter->device_mode),
11122 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011123
11124 if (CSR_MAX_NUM_KEY <= key_index)
11125 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011126 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011127 key_index);
11128
11129 return -EINVAL;
11130 }
11131
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011132 if (CSR_MAX_KEY_LEN < params->key_len)
11133 {
11134 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11135 params->key_len);
11136
11137 return -EINVAL;
11138 }
11139
11140 hddLog(VOS_TRACE_LEVEL_INFO,
11141 "%s: called with key index = %d & key length %d",
11142 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011143
11144 /*extract key idx, key len and key*/
11145 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11146 setKey.keyId = key_index;
11147 setKey.keyLength = params->key_len;
11148 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11149
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011150 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 {
11152 case WLAN_CIPHER_SUITE_WEP40:
11153 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11154 break;
11155
11156 case WLAN_CIPHER_SUITE_WEP104:
11157 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11158 break;
11159
11160 case WLAN_CIPHER_SUITE_TKIP:
11161 {
11162 u8 *pKey = &setKey.Key[0];
11163 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11164
11165 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11166
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011167 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011168
11169 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011170 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011171 |--------------|----------|----------|
11172 <---16bytes---><--8bytes--><--8bytes-->
11173
11174 */
11175 /*Sme expects the 32 bytes key to be in the below order
11176
11177 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011178 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011179 |--------------|----------|----------|
11180 <---16bytes---><--8bytes--><--8bytes-->
11181 */
11182 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011183 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011184
11185 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011186 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011187
11188 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011189 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011190
11191
11192 break;
11193 }
11194
11195 case WLAN_CIPHER_SUITE_CCMP:
11196 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11197 break;
11198
11199#ifdef FEATURE_WLAN_WAPI
11200 case WLAN_CIPHER_SUITE_SMS4:
11201 {
11202 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11203 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11204 params->key, params->key_len);
11205 return 0;
11206 }
11207#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011208
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011209#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011210 case WLAN_CIPHER_SUITE_KRK:
11211 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11212 break;
11213#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011214
11215#ifdef WLAN_FEATURE_11W
11216 case WLAN_CIPHER_SUITE_AES_CMAC:
11217 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011218 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011219#endif
11220
Jeff Johnson295189b2012-06-20 16:38:30 -070011221 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011222 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011223 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011224 status = -EOPNOTSUPP;
11225 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011226 }
11227
11228 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11229 __func__, setKey.encType);
11230
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011231 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011232#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11233 (!pairwise)
11234#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011235 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011236#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011237 )
11238 {
11239 /* set group key*/
11240 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11241 "%s- %d: setting Broadcast key",
11242 __func__, __LINE__);
11243 setKey.keyDirection = eSIR_RX_ONLY;
11244 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11245 }
11246 else
11247 {
11248 /* set pairwise key*/
11249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11250 "%s- %d: setting pairwise key",
11251 __func__, __LINE__);
11252 setKey.keyDirection = eSIR_TX_RX;
11253 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11254 }
11255 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11256 {
11257 setKey.keyDirection = eSIR_TX_RX;
11258 /*Set the group key*/
11259 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11260 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011261
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011262 if ( 0 != status )
11263 {
11264 hddLog(VOS_TRACE_LEVEL_ERROR,
11265 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011266 status = -EINVAL;
11267 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011268 }
11269 /*Save the keys here and call sme_RoamSetKey for setting
11270 the PTK after peer joins the IBSS network*/
11271 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11272 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011273 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011274 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011275 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11276 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11277 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011278 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011279 if( pHostapdState->bssState == BSS_START )
11280 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011281 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11282 vos_status = wlan_hdd_check_ula_done(pAdapter);
11283
11284 if ( vos_status != VOS_STATUS_SUCCESS )
11285 {
11286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11287 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11288 __LINE__, vos_status );
11289
11290 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11291
11292 status = -EINVAL;
11293 goto end;
11294 }
11295
Jeff Johnson295189b2012-06-20 16:38:30 -070011296 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11297
11298 if ( status != eHAL_STATUS_SUCCESS )
11299 {
11300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11301 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11302 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011303 status = -EINVAL;
11304 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011305 }
11306 }
11307
11308 /* Saving WEP keys */
11309 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11310 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11311 {
11312 //Save the wep key in ap context. Issue setkey after the BSS is started.
11313 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11314 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11315 }
11316 else
11317 {
11318 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011319 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011320 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11321 }
11322 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011323 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11324 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011325 {
11326 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11327 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11328
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011329#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11330 if (!pairwise)
11331#else
11332 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11333#endif
11334 {
11335 /* set group key*/
11336 if (pHddStaCtx->roam_info.deferKeyComplete)
11337 {
11338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11339 "%s- %d: Perform Set key Complete",
11340 __func__, __LINE__);
11341 hdd_PerformRoamSetKeyComplete(pAdapter);
11342 }
11343 }
11344
Jeff Johnson295189b2012-06-20 16:38:30 -070011345 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11346
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011347 pWextState->roamProfile.Keys.defaultIndex = key_index;
11348
11349
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011350 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011351 params->key, params->key_len);
11352
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011353
Jeff Johnson295189b2012-06-20 16:38:30 -070011354 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11355
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011356 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011357 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011358 __func__, setKey.peerMac[0], setKey.peerMac[1],
11359 setKey.peerMac[2], setKey.peerMac[3],
11360 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011361 setKey.keyDirection);
11362
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011363 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011364
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011365 if ( vos_status != VOS_STATUS_SUCCESS )
11366 {
11367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011368 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11369 __LINE__, vos_status );
11370
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011371 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011372
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011373 status = -EINVAL;
11374 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011375
11376 }
11377
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011378#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011379 /* The supplicant may attempt to set the PTK once pre-authentication
11380 is done. Save the key in the UMAC and include it in the ADD BSS
11381 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011382 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011383 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011384 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011385 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11386 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011387 status = 0;
11388 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011389 }
11390 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11391 {
11392 hddLog(VOS_TRACE_LEVEL_ERROR,
11393 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011394 status = -EINVAL;
11395 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011396 }
11397#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011398
11399 /* issue set key request to SME*/
11400 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11401 pAdapter->sessionId, &setKey, &roamId );
11402
11403 if ( 0 != status )
11404 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011405 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011406 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11407 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011408 status = -EINVAL;
11409 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011410 }
11411
11412
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011413 /* in case of IBSS as there was no information available about WEP keys during
11414 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011415 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011416 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11417 !( ( IW_AUTH_KEY_MGMT_802_1X
11418 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011419 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11420 )
11421 &&
11422 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11423 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11424 )
11425 )
11426 {
11427 setKey.keyDirection = eSIR_RX_ONLY;
11428 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11429
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011430 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011431 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011432 __func__, setKey.peerMac[0], setKey.peerMac[1],
11433 setKey.peerMac[2], setKey.peerMac[3],
11434 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011435 setKey.keyDirection);
11436
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011437 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011438 pAdapter->sessionId, &setKey, &roamId );
11439
11440 if ( 0 != status )
11441 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011442 hddLog(VOS_TRACE_LEVEL_ERROR,
11443 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011444 __func__, status);
11445 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011446 status = -EINVAL;
11447 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011448 }
11449 }
11450 }
11451
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011452end:
11453 /* Need to clear any trace of key value in the memory.
11454 * Thus zero out the memory even though it is local
11455 * variable.
11456 */
11457 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011458 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011459 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011460}
11461
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011462#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11463static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11464 struct net_device *ndev,
11465 u8 key_index, bool pairwise,
11466 const u8 *mac_addr,
11467 struct key_params *params
11468 )
11469#else
11470static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11471 struct net_device *ndev,
11472 u8 key_index, const u8 *mac_addr,
11473 struct key_params *params
11474 )
11475#endif
11476{
11477 int ret;
11478 vos_ssr_protect(__func__);
11479#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11480 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11481 mac_addr, params);
11482#else
11483 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11484 params);
11485#endif
11486 vos_ssr_unprotect(__func__);
11487
11488 return ret;
11489}
11490
Jeff Johnson295189b2012-06-20 16:38:30 -070011491/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011492 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011493 * This function is used to get the key information
11494 */
11495#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011496static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011497 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011498 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011499 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011500 const u8 *mac_addr, void *cookie,
11501 void (*callback)(void *cookie, struct key_params*)
11502 )
11503#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011504static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011505 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011506 struct net_device *ndev,
11507 u8 key_index, const u8 *mac_addr, void *cookie,
11508 void (*callback)(void *cookie, struct key_params*)
11509 )
11510#endif
11511{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011512 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011513 hdd_wext_state_t *pWextState = NULL;
11514 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011515 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011516 hdd_context_t *pHddCtx;
11517 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011518
11519 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011520
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011521 if (NULL == pAdapter)
11522 {
11523 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11524 "%s: HDD adapter is Null", __func__);
11525 return -ENODEV;
11526 }
11527
11528 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11529 ret = wlan_hdd_validate_context(pHddCtx);
11530 if (0 != ret)
11531 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011532 return ret;
11533 }
11534
11535 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11536 pRoamProfile = &(pWextState->roamProfile);
11537
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011538 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11539 __func__, hdd_device_modetoString(pAdapter->device_mode),
11540 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011541
Jeff Johnson295189b2012-06-20 16:38:30 -070011542 memset(&params, 0, sizeof(params));
11543
11544 if (CSR_MAX_NUM_KEY <= key_index)
11545 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011546 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011547 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011548 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011549
11550 switch(pRoamProfile->EncryptionType.encryptionType[0])
11551 {
11552 case eCSR_ENCRYPT_TYPE_NONE:
11553 params.cipher = IW_AUTH_CIPHER_NONE;
11554 break;
11555
11556 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11557 case eCSR_ENCRYPT_TYPE_WEP40:
11558 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11559 break;
11560
11561 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11562 case eCSR_ENCRYPT_TYPE_WEP104:
11563 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11564 break;
11565
11566 case eCSR_ENCRYPT_TYPE_TKIP:
11567 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11568 break;
11569
11570 case eCSR_ENCRYPT_TYPE_AES:
11571 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11572 break;
11573
11574 default:
11575 params.cipher = IW_AUTH_CIPHER_NONE;
11576 break;
11577 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011578
c_hpothuaaf19692014-05-17 17:01:48 +053011579 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11580 TRACE_CODE_HDD_CFG80211_GET_KEY,
11581 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011582
Jeff Johnson295189b2012-06-20 16:38:30 -070011583 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11584 params.seq_len = 0;
11585 params.seq = NULL;
11586 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11587 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011588 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011589 return 0;
11590}
11591
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011592#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11593static int wlan_hdd_cfg80211_get_key(
11594 struct wiphy *wiphy,
11595 struct net_device *ndev,
11596 u8 key_index, bool pairwise,
11597 const u8 *mac_addr, void *cookie,
11598 void (*callback)(void *cookie, struct key_params*)
11599 )
11600#else
11601static int wlan_hdd_cfg80211_get_key(
11602 struct wiphy *wiphy,
11603 struct net_device *ndev,
11604 u8 key_index, const u8 *mac_addr, void *cookie,
11605 void (*callback)(void *cookie, struct key_params*)
11606 )
11607#endif
11608{
11609 int ret;
11610
11611 vos_ssr_protect(__func__);
11612#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11613 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
11614 mac_addr, cookie, callback);
11615#else
11616 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
11617 callback);
11618#endif
11619 vos_ssr_unprotect(__func__);
11620
11621 return ret;
11622}
11623
Jeff Johnson295189b2012-06-20 16:38:30 -070011624/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011625 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011626 * This function is used to delete the key information
11627 */
11628#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011629static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011630 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011631 u8 key_index,
11632 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011633 const u8 *mac_addr
11634 )
11635#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011636static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011637 struct net_device *ndev,
11638 u8 key_index,
11639 const u8 *mac_addr
11640 )
11641#endif
11642{
11643 int status = 0;
11644
11645 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011646 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070011647 //it is observed that this is invalidating peer
11648 //key index whenever re-key is done. This is affecting data link.
11649 //It should be ok to ignore del_key.
11650#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011651 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
11652 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011653 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11654 tCsrRoamSetKey setKey;
11655 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011656
Jeff Johnson295189b2012-06-20 16:38:30 -070011657 ENTER();
11658
11659 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
11660 __func__,pAdapter->device_mode);
11661
11662 if (CSR_MAX_NUM_KEY <= key_index)
11663 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011664 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011665 key_index);
11666
11667 return -EINVAL;
11668 }
11669
11670 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11671 setKey.keyId = key_index;
11672
11673 if (mac_addr)
11674 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11675 else
11676 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
11677
11678 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
11679
11680 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011681 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011682 )
11683 {
11684
11685 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070011686 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11687 if( pHostapdState->bssState == BSS_START)
11688 {
11689 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011690
Jeff Johnson295189b2012-06-20 16:38:30 -070011691 if ( status != eHAL_STATUS_SUCCESS )
11692 {
11693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11694 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11695 __LINE__, status );
11696 }
11697 }
11698 }
11699 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011700 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070011701 )
11702 {
11703 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11704
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011705 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11706
11707 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011708 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011709 __func__, setKey.peerMac[0], setKey.peerMac[1],
11710 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070011711 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011712 if(pAdapter->sessionCtx.station.conn_info.connState ==
11713 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070011714 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011715 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011716 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011717
Jeff Johnson295189b2012-06-20 16:38:30 -070011718 if ( 0 != status )
11719 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011720 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011721 "%s: sme_RoamSetKey failure, returned %d",
11722 __func__, status);
11723 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11724 return -EINVAL;
11725 }
11726 }
11727 }
11728#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011729 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011730 return status;
11731}
11732
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011733#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11734static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11735 struct net_device *ndev,
11736 u8 key_index,
11737 bool pairwise,
11738 const u8 *mac_addr
11739 )
11740#else
11741static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11742 struct net_device *ndev,
11743 u8 key_index,
11744 const u8 *mac_addr
11745 )
11746#endif
11747{
11748 int ret;
11749
11750 vos_ssr_protect(__func__);
11751#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11752 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
11753 mac_addr);
11754#else
11755 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
11756#endif
11757 vos_ssr_unprotect(__func__);
11758
11759 return ret;
11760}
11761
Jeff Johnson295189b2012-06-20 16:38:30 -070011762/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011763 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011764 * This function is used to set the default tx key index
11765 */
11766#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011767static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011768 struct net_device *ndev,
11769 u8 key_index,
11770 bool unicast, bool multicast)
11771#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011772static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011773 struct net_device *ndev,
11774 u8 key_index)
11775#endif
11776{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011777 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011778 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011779 hdd_wext_state_t *pWextState;
11780 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011781 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011782
11783 ENTER();
11784
Gopichand Nakkala29149562013-05-10 21:43:41 +053011785 if ((NULL == pAdapter))
11786 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011787 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011788 "invalid adapter");
11789 return -EINVAL;
11790 }
11791
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011792 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11793 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
11794 pAdapter->sessionId, key_index));
11795
Gopichand Nakkala29149562013-05-10 21:43:41 +053011796 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11797 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11798
11799 if ((NULL == pWextState) || (NULL == pHddStaCtx))
11800 {
11801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11802 "invalid Wext state or HDD context");
11803 return -EINVAL;
11804 }
11805
Arif Hussain6d2a3322013-11-17 19:50:10 -080011806 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011807 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011808
Jeff Johnson295189b2012-06-20 16:38:30 -070011809 if (CSR_MAX_NUM_KEY <= key_index)
11810 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011811 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011812 key_index);
11813
11814 return -EINVAL;
11815 }
11816
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011817 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11818 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011819 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011820 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011821 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011822 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011823
Jeff Johnson295189b2012-06-20 16:38:30 -070011824 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011825 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011826 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011827 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011828 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080011829 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011830 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080011831 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070011832 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011833 {
11834 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070011835 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011836
Jeff Johnson295189b2012-06-20 16:38:30 -070011837 tCsrRoamSetKey setKey;
11838 v_U32_t roamId= 0xFF;
11839 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011840
11841 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011842 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011843
Jeff Johnson295189b2012-06-20 16:38:30 -070011844 Keys->defaultIndex = (u8)key_index;
11845 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11846 setKey.keyId = key_index;
11847 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011848
11849 vos_mem_copy(&setKey.Key[0],
11850 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011851 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011852
Gopichand Nakkala29149562013-05-10 21:43:41 +053011853 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011854
11855 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070011856 &pHddStaCtx->conn_info.bssId[0],
11857 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011858
Gopichand Nakkala29149562013-05-10 21:43:41 +053011859 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
11860 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
11861 eCSR_ENCRYPT_TYPE_WEP104)
11862 {
11863 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
11864 even though ap is configured for WEP-40 encryption. In this canse the key length
11865 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
11866 type(104) and switching encryption type to 40*/
11867 pWextState->roamProfile.EncryptionType.encryptionType[0] =
11868 eCSR_ENCRYPT_TYPE_WEP40;
11869 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
11870 eCSR_ENCRYPT_TYPE_WEP40;
11871 }
11872
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011873 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011874 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011875
Jeff Johnson295189b2012-06-20 16:38:30 -070011876 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011877 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011878 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011879
Jeff Johnson295189b2012-06-20 16:38:30 -070011880 if ( 0 != status )
11881 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011882 hddLog(VOS_TRACE_LEVEL_ERROR,
11883 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011884 status);
11885 return -EINVAL;
11886 }
11887 }
11888 }
11889
11890 /* In SoftAp mode setting key direction for default mode */
11891 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
11892 {
11893 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
11894 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
11895 (eCSR_ENCRYPT_TYPE_AES !=
11896 pWextState->roamProfile.EncryptionType.encryptionType[0])
11897 )
11898 {
11899 /* Saving key direction for default key index to TX default */
11900 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11901 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
11902 }
11903 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011904 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011905 return status;
11906}
11907
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011908#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11909static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11910 struct net_device *ndev,
11911 u8 key_index,
11912 bool unicast, bool multicast)
11913#else
11914static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11915 struct net_device *ndev,
11916 u8 key_index)
11917#endif
11918{
11919 int ret;
11920 vos_ssr_protect(__func__);
11921#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11922 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
11923 multicast);
11924#else
11925 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
11926#endif
11927 vos_ssr_unprotect(__func__);
11928
11929 return ret;
11930}
11931
Jeff Johnson295189b2012-06-20 16:38:30 -070011932/*
11933 * FUNCTION: wlan_hdd_cfg80211_inform_bss
11934 * This function is used to inform the BSS details to nl80211 interface.
11935 */
11936static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
11937 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
11938{
11939 struct net_device *dev = pAdapter->dev;
11940 struct wireless_dev *wdev = dev->ieee80211_ptr;
11941 struct wiphy *wiphy = wdev->wiphy;
11942 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
11943 int chan_no;
11944 int ie_length;
11945 const char *ie;
11946 unsigned int freq;
11947 struct ieee80211_channel *chan;
11948 int rssi = 0;
11949 struct cfg80211_bss *bss = NULL;
11950
Jeff Johnson295189b2012-06-20 16:38:30 -070011951 if( NULL == pBssDesc )
11952 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011953 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011954 return bss;
11955 }
11956
11957 chan_no = pBssDesc->channelId;
11958 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
11959 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
11960
11961 if( NULL == ie )
11962 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011963 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011964 return bss;
11965 }
11966
11967#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
11968 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
11969 {
11970 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
11971 }
11972 else
11973 {
11974 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
11975 }
11976#else
11977 freq = ieee80211_channel_to_frequency(chan_no);
11978#endif
11979
11980 chan = __ieee80211_get_channel(wiphy, freq);
11981
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053011982 if (!chan) {
11983 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
11984 return NULL;
11985 }
11986
Abhishek Singhaee43942014-06-16 18:55:47 +053011987 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070011988
Anand N Sunkad9f80b742015-07-30 20:05:51 +053011989 return cfg80211_inform_bss(wiphy, chan,
11990#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11991 CFG80211_BSS_FTYPE_UNKNOWN,
11992#endif
11993 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011994 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070011995 pBssDesc->capabilityInfo,
11996 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053011997 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070011998}
11999
12000
12001
12002/*
12003 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12004 * This function is used to inform the BSS details to nl80211 interface.
12005 */
12006struct cfg80211_bss*
12007wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12008 tSirBssDescription *bss_desc
12009 )
12010{
12011 /*
12012 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12013 already exists in bss data base of cfg80211 for that particular BSS ID.
12014 Using cfg80211_inform_bss_frame to update the bss entry instead of
12015 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12016 now there is no possibility to get the mgmt(probe response) frame from PE,
12017 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12018 cfg80211_inform_bss_frame.
12019 */
12020 struct net_device *dev = pAdapter->dev;
12021 struct wireless_dev *wdev = dev->ieee80211_ptr;
12022 struct wiphy *wiphy = wdev->wiphy;
12023 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012024#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12025 qcom_ie_age *qie_age = NULL;
12026 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12027#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012028 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012029#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012030 const char *ie =
12031 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12032 unsigned int freq;
12033 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012034 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012035 struct cfg80211_bss *bss_status = NULL;
12036 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12037 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012038 hdd_context_t *pHddCtx;
12039 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012040#ifdef WLAN_OPEN_SOURCE
12041 struct timespec ts;
12042#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012043
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012044
Wilson Yangf80a0542013-10-07 13:02:37 -070012045 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12046 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012047 if (0 != status)
12048 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012049 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012050 }
12051
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012052 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012053 if (!mgmt)
12054 {
12055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12056 "%s: memory allocation failed ", __func__);
12057 return NULL;
12058 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012059
Jeff Johnson295189b2012-06-20 16:38:30 -070012060 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012061
12062#ifdef WLAN_OPEN_SOURCE
12063 /* Android does not want the timestamp from the frame.
12064 Instead it wants a monotonic increasing value */
12065 get_monotonic_boottime(&ts);
12066 mgmt->u.probe_resp.timestamp =
12067 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12068#else
12069 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012070 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12071 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012072
12073#endif
12074
Jeff Johnson295189b2012-06-20 16:38:30 -070012075 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12076 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012077
12078#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12079 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12080 /* Assuming this is the last IE, copy at the end */
12081 ie_length -=sizeof(qcom_ie_age);
12082 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12083 qie_age->element_id = QCOM_VENDOR_IE_ID;
12084 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12085 qie_age->oui_1 = QCOM_OUI1;
12086 qie_age->oui_2 = QCOM_OUI2;
12087 qie_age->oui_3 = QCOM_OUI3;
12088 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
12089 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
12090#endif
12091
Jeff Johnson295189b2012-06-20 16:38:30 -070012092 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012093 if (bss_desc->fProbeRsp)
12094 {
12095 mgmt->frame_control |=
12096 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12097 }
12098 else
12099 {
12100 mgmt->frame_control |=
12101 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12102 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012103
12104#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012105 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012106 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12107 {
12108 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12109 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012110 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012111 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12112
12113 {
12114 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12115 }
12116 else
12117 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012118 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12119 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012120 kfree(mgmt);
12121 return NULL;
12122 }
12123#else
12124 freq = ieee80211_channel_to_frequency(chan_no);
12125#endif
12126 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012127 /*when the band is changed on the fly using the GUI, three things are done
12128 * 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)
12129 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12130 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12131 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12132 * and discards the channels correponding to previous band and calls back with zero bss results.
12133 * 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
12134 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12135 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12136 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12137 * So drop the bss and continue to next bss.
12138 */
12139 if(chan == NULL)
12140 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012141 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070012142 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012143 return NULL;
12144 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012145 /*To keep the rssi icon of the connected AP in the scan window
12146 *and the rssi icon of the wireless networks in sync
12147 * */
12148 if (( eConnectionState_Associated ==
12149 pAdapter->sessionCtx.station.conn_info.connState ) &&
12150 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12151 pAdapter->sessionCtx.station.conn_info.bssId,
12152 WNI_CFG_BSSID_LEN)) &&
12153 (pHddCtx->hdd_wlan_suspended == FALSE))
12154 {
12155 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12156 rssi = (pAdapter->rssi * 100);
12157 }
12158 else
12159 {
12160 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12161 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012162
Nirav Shah20ac06f2013-12-12 18:14:06 +053012163 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012164 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12165 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012166
Jeff Johnson295189b2012-06-20 16:38:30 -070012167 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12168 frame_len, rssi, GFP_KERNEL);
12169 kfree(mgmt);
12170 return bss_status;
12171}
12172
12173/*
12174 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12175 * This function is used to update the BSS data base of CFG8011
12176 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012177struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012178 tCsrRoamInfo *pRoamInfo
12179 )
12180{
12181 tCsrRoamConnectedProfile roamProfile;
12182 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12183 struct cfg80211_bss *bss = NULL;
12184
12185 ENTER();
12186
12187 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12188 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12189
12190 if (NULL != roamProfile.pBssDesc)
12191 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012192 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12193 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012194
12195 if (NULL == bss)
12196 {
12197 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12198 __func__);
12199 }
12200
12201 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12202 }
12203 else
12204 {
12205 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12206 __func__);
12207 }
12208 return bss;
12209}
12210
12211/*
12212 * FUNCTION: wlan_hdd_cfg80211_update_bss
12213 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012214static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12215 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012216 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012217{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012218 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012219 tCsrScanResultInfo *pScanResult;
12220 eHalStatus status = 0;
12221 tScanResultHandle pResult;
12222 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012223 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012224 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012225 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012226
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012227 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12228 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12229 NO_SESSION, pAdapter->sessionId));
12230
Wilson Yangf80a0542013-10-07 13:02:37 -070012231 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12232
12233 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070012234 {
Wilson Yangf80a0542013-10-07 13:02:37 -070012235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12236 "%s:LOGP in Progress. Ignore!!!",__func__);
12237 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070012238 }
12239
Wilson Yangf80a0542013-10-07 13:02:37 -070012240
12241 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053012242 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070012243 {
12244 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12245 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
12246 return VOS_STATUS_E_PERM;
12247 }
12248
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012249 if (pAdapter->request != NULL)
12250 {
12251 if ((pAdapter->request->n_ssids == 1)
12252 && (pAdapter->request->ssids != NULL)
12253 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12254 is_p2p_scan = true;
12255 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012256 /*
12257 * start getting scan results and populate cgf80211 BSS database
12258 */
12259 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12260
12261 /* no scan results */
12262 if (NULL == pResult)
12263 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012264 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12265 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012266 wlan_hdd_get_frame_logs(pAdapter,
12267 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012268 return status;
12269 }
12270
12271 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12272
12273 while (pScanResult)
12274 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012275 /*
12276 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12277 * entry already exists in bss data base of cfg80211 for that
12278 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12279 * bss entry instead of cfg80211_inform_bss, But this call expects
12280 * mgmt packet as input. As of now there is no possibility to get
12281 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012282 * ieee80211_mgmt(probe response) and passing to c
12283 * fg80211_inform_bss_frame.
12284 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012285 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12286 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12287 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012288 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12289 continue; //Skip the non p2p bss entries
12290 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012291 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12292 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012293
Jeff Johnson295189b2012-06-20 16:38:30 -070012294
12295 if (NULL == bss_status)
12296 {
12297 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012298 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012299 }
12300 else
12301 {
Yue Maf49ba872013-08-19 12:04:25 -070012302 cfg80211_put_bss(
12303#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12304 wiphy,
12305#endif
12306 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012307 }
12308
12309 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12310 }
12311
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012312 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012313 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012314 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012315}
12316
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012317void
12318hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12319{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012320 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012321 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012322} /****** end hddPrintMacAddr() ******/
12323
12324void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012325hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012326{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012327 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012328 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012329 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12330 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12331 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012332} /****** end hddPrintPmkId() ******/
12333
12334//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12335//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12336
12337//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12338//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12339
12340#define dump_bssid(bssid) \
12341 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012342 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12343 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012344 }
12345
12346#define dump_pmkid(pMac, pmkid) \
12347 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012348 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12349 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012350 }
12351
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012352#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012353/*
12354 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12355 * This function is used to notify the supplicant of a new PMKSA candidate.
12356 */
12357int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012358 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012359 int index, bool preauth )
12360{
Jeff Johnsone7245742012-09-05 17:12:55 -070012361#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012362 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012363 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012364
12365 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012366 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012367
12368 if( NULL == pRoamInfo )
12369 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012370 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012371 return -EINVAL;
12372 }
12373
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012374 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12375 {
12376 dump_bssid(pRoamInfo->bssid);
12377 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012378 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012379 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012380#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012381 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012382}
12383#endif //FEATURE_WLAN_LFR
12384
Yue Maef608272013-04-08 23:09:17 -070012385#ifdef FEATURE_WLAN_LFR_METRICS
12386/*
12387 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12388 * 802.11r/LFR metrics reporting function to report preauth initiation
12389 *
12390 */
12391#define MAX_LFR_METRICS_EVENT_LENGTH 100
12392VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12393 tCsrRoamInfo *pRoamInfo)
12394{
12395 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12396 union iwreq_data wrqu;
12397
12398 ENTER();
12399
12400 if (NULL == pAdapter)
12401 {
12402 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12403 return VOS_STATUS_E_FAILURE;
12404 }
12405
12406 /* create the event */
12407 memset(&wrqu, 0, sizeof(wrqu));
12408 memset(metrics_notification, 0, sizeof(metrics_notification));
12409
12410 wrqu.data.pointer = metrics_notification;
12411 wrqu.data.length = scnprintf(metrics_notification,
12412 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12413 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12414
12415 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12416
12417 EXIT();
12418
12419 return VOS_STATUS_SUCCESS;
12420}
12421
12422/*
12423 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12424 * 802.11r/LFR metrics reporting function to report preauth completion
12425 * or failure
12426 */
12427VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12428 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12429{
12430 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12431 union iwreq_data wrqu;
12432
12433 ENTER();
12434
12435 if (NULL == pAdapter)
12436 {
12437 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12438 return VOS_STATUS_E_FAILURE;
12439 }
12440
12441 /* create the event */
12442 memset(&wrqu, 0, sizeof(wrqu));
12443 memset(metrics_notification, 0, sizeof(metrics_notification));
12444
12445 scnprintf(metrics_notification, sizeof(metrics_notification),
12446 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12447 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12448
12449 if (1 == preauth_status)
12450 strncat(metrics_notification, " TRUE", 5);
12451 else
12452 strncat(metrics_notification, " FALSE", 6);
12453
12454 wrqu.data.pointer = metrics_notification;
12455 wrqu.data.length = strlen(metrics_notification);
12456
12457 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12458
12459 EXIT();
12460
12461 return VOS_STATUS_SUCCESS;
12462}
12463
12464/*
12465 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12466 * 802.11r/LFR metrics reporting function to report handover initiation
12467 *
12468 */
12469VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12470 tCsrRoamInfo *pRoamInfo)
12471{
12472 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12473 union iwreq_data wrqu;
12474
12475 ENTER();
12476
12477 if (NULL == pAdapter)
12478 {
12479 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12480 return VOS_STATUS_E_FAILURE;
12481 }
12482
12483 /* create the event */
12484 memset(&wrqu, 0, sizeof(wrqu));
12485 memset(metrics_notification, 0, sizeof(metrics_notification));
12486
12487 wrqu.data.pointer = metrics_notification;
12488 wrqu.data.length = scnprintf(metrics_notification,
12489 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12490 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12491
12492 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12493
12494 EXIT();
12495
12496 return VOS_STATUS_SUCCESS;
12497}
12498#endif
12499
Jeff Johnson295189b2012-06-20 16:38:30 -070012500/*
12501 * FUNCTION: hdd_cfg80211_scan_done_callback
12502 * scanning callback function, called after finishing scan
12503 *
12504 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012505static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012506 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12507{
12508 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012509 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012510 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012511 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012512 struct cfg80211_scan_request *req = NULL;
12513 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012514 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012515 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012516 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012517 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012518
12519 ENTER();
12520
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012521 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012522 if (NULL == pHddCtx) {
12523 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012524 goto allow_suspend;
12525 }
12526
12527 pScanInfo = &pHddCtx->scan_info;
12528
Jeff Johnson295189b2012-06-20 16:38:30 -070012529 hddLog(VOS_TRACE_LEVEL_INFO,
12530 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012531 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012532 __func__, halHandle, pContext, (int) scanId, (int) status);
12533
Kiet Lamac06e2c2013-10-23 16:25:07 +053012534 pScanInfo->mScanPendingCounter = 0;
12535
Jeff Johnson295189b2012-06-20 16:38:30 -070012536 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012537 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012538 &pScanInfo->scan_req_completion_event,
12539 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012540 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012541 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012542 hddLog(VOS_TRACE_LEVEL_ERROR,
12543 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012544 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012545 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012546 }
12547
Yue Maef608272013-04-08 23:09:17 -070012548 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012549 {
12550 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012551 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012552 }
12553
12554 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012555 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012556 {
12557 hddLog(VOS_TRACE_LEVEL_INFO,
12558 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012559 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012560 (int) scanId);
12561 }
12562
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012563 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012564 pAdapter);
12565
12566 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012567 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012568
12569
12570 /* If any client wait scan result through WEXT
12571 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012572 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012573 {
12574 /* The other scan request waiting for current scan finish
12575 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012576 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012577 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012578 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012579 }
12580 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012581 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012582 {
12583 struct net_device *dev = pAdapter->dev;
12584 union iwreq_data wrqu;
12585 int we_event;
12586 char *msg;
12587
12588 memset(&wrqu, '\0', sizeof(wrqu));
12589 we_event = SIOCGIWSCAN;
12590 msg = NULL;
12591 wireless_send_event(dev, we_event, &wrqu, msg);
12592 }
12593 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012594 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012595
12596 /* Get the Scan Req */
12597 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053012598 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012599
mukul sharmae7041822015-12-03 15:09:21 +053012600 if (!req || req->wiphy == NULL)
Jeff Johnson295189b2012-06-20 16:38:30 -070012601 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012602 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012603 pScanInfo->mScanPending = VOS_FALSE;
mukul sharmae7041822015-12-03 15:09:21 +053012604 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070012605 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012606 }
12607
Jeff Johnson295189b2012-06-20 16:38:30 -070012608 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070012609 /* Scan is no longer pending */
12610 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012611
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012612 /* last_scan_timestamp is used to decide if new scan
12613 * is needed or not on station interface. If last station
12614 * scan time and new station scan time is less then
12615 * last_scan_timestamp ; driver will return cached scan.
12616 */
12617 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12618 {
12619 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12620
12621 if ( req->n_channels )
12622 {
12623 for (i = 0; i < req->n_channels ; i++ )
12624 {
12625 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12626 }
12627 /* store no of channel scanned */
12628 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
12629 }
12630
12631 }
12632
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070012633 /*
12634 * cfg80211_scan_done informing NL80211 about completion
12635 * of scanning
12636 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012637 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
12638 {
12639 aborted = true;
12640 }
mukul sharmae7041822015-12-03 15:09:21 +053012641
12642#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Arun Khandavalli2aba40a2015-12-04 15:53:37 +053012643 if (pAdapter->dev->flags & IFF_UP)
mukul sharmae7041822015-12-03 15:09:21 +053012644#endif
12645 cfg80211_scan_done(req, aborted);
12646
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012647 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070012648
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053012649 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
12650 ) && (pHddCtx->spoofMacAddr.isEnabled
12651 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053012652 /* Generate new random mac addr for next scan */
12653 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053012654
12655 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
12656 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053012657 }
12658
Jeff Johnsone7245742012-09-05 17:12:55 -070012659allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012660 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012661 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012662
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012663 /* Acquire wakelock to handle the case where APP's tries to suspend
12664 * immediatly after the driver gets connect request(i.e after scan)
12665 * from supplicant, this result in app's is suspending and not able
12666 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012667 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012668
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012669#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053012670 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012671#endif
12672
Jeff Johnson295189b2012-06-20 16:38:30 -070012673 EXIT();
12674 return 0;
12675}
12676
12677/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053012678 * FUNCTION: hdd_isConnectionInProgress
12679 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012680 *
12681 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012682v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012683{
12684 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12685 hdd_station_ctx_t *pHddStaCtx = NULL;
12686 hdd_adapter_t *pAdapter = NULL;
12687 VOS_STATUS status = 0;
12688 v_U8_t staId = 0;
12689 v_U8_t *staMac = NULL;
12690
c_hpothu9b781ba2013-12-30 20:57:45 +053012691 if (TRUE == pHddCtx->btCoexModeSet)
12692 {
12693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053012694 FL("BTCoex Mode operation in progress"));
12695 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053012696 }
12697
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012698 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12699
12700 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12701 {
12702 pAdapter = pAdapterNode->pAdapter;
12703
12704 if( pAdapter )
12705 {
12706 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012707 "%s: Adapter with device mode %s (%d) exists",
12708 __func__, hdd_device_modetoString(pAdapter->device_mode),
12709 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012710 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053012711 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12712 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
12713 (eConnectionState_Connecting ==
12714 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12715 {
12716 hddLog(VOS_TRACE_LEVEL_ERROR,
12717 "%s: %p(%d) Connection is in progress", __func__,
12718 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12719 return VOS_TRUE;
12720 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012721 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053012722 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012723 {
12724 hddLog(VOS_TRACE_LEVEL_ERROR,
12725 "%s: %p(%d) Reassociation is in progress", __func__,
12726 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12727 return VOS_TRUE;
12728 }
12729 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012730 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12731 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012732 {
12733 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12734 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012735 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012736 {
12737 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
12738 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012739 "%s: client " MAC_ADDRESS_STR
12740 " is in the middle of WPS/EAPOL exchange.", __func__,
12741 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012742 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012743 }
12744 }
12745 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
12746 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
12747 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012748 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12749 ptSapContext pSapCtx = NULL;
12750 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12751 if(pSapCtx == NULL){
12752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12753 FL("psapCtx is NULL"));
12754 return VOS_FALSE;
12755 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012756 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
12757 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012758 if ((pSapCtx->aStaInfo[staId].isUsed) &&
12759 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012760 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012761 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012762
12763 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012764 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
12765 "middle of WPS/EAPOL exchange.", __func__,
12766 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012767 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012768 }
12769 }
12770 }
12771 }
12772 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12773 pAdapterNode = pNext;
12774 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053012775 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012776}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012777
12778/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012779 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070012780 * this scan respond to scan trigger and update cfg80211 scan database
12781 * later, scan dump command can be used to recieve scan results
12782 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012783int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080012784#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12785 struct net_device *dev,
12786#endif
12787 struct cfg80211_scan_request *request)
12788{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012789 hdd_adapter_t *pAdapter = NULL;
12790 hdd_context_t *pHddCtx = NULL;
12791 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012792 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012793 tCsrScanRequest scanRequest;
12794 tANI_U8 *channelList = NULL, i;
12795 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012796 int status;
12797 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012798 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012799 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053012800 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053012801 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012802 v_S7_t rssi=0;
12803 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012804
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012805#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
12806 struct net_device *dev = NULL;
12807 if (NULL == request)
12808 {
12809 hddLog(VOS_TRACE_LEVEL_ERROR,
12810 "%s: scan req param null", __func__);
12811 return -EINVAL;
12812 }
12813 dev = request->wdev->netdev;
12814#endif
12815
12816 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12817 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
12818 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12819
Jeff Johnson295189b2012-06-20 16:38:30 -070012820 ENTER();
12821
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012822 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12823 __func__, hdd_device_modetoString(pAdapter->device_mode),
12824 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012825
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012826 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012827 if (0 != status)
12828 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012829 return status;
12830 }
12831
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012832 if (NULL == pwextBuf)
12833 {
12834 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
12835 __func__);
12836 return -EIO;
12837 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012838 cfg_param = pHddCtx->cfg_ini;
12839 pScanInfo = &pHddCtx->scan_info;
12840
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012841 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12842 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
12843 {
12844 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
12845 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
12846 }
12847
Jeff Johnson295189b2012-06-20 16:38:30 -070012848#ifdef WLAN_BTAMP_FEATURE
12849 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012850 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070012851 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080012852 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012853 "%s: No scanning when AMP is on", __func__);
12854 return -EOPNOTSUPP;
12855 }
12856#endif
12857 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012858 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012859 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012860 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012861 "%s: Not scanning on device_mode = %s (%d)",
12862 __func__, hdd_device_modetoString(pAdapter->device_mode),
12863 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012864 return -EOPNOTSUPP;
12865 }
12866
12867 if (TRUE == pScanInfo->mScanPending)
12868 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012869 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
12870 {
12871 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
12872 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012873 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012874 }
12875
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053012876 // Don't allow scan if PNO scan is going on.
12877 if (pHddCtx->isPnoEnable)
12878 {
12879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12880 FL("pno scan in progress"));
12881 return -EBUSY;
12882 }
12883
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012884 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070012885 //Channel and action frame is pending
12886 //Otherwise Cancel Remain On Channel and allow Scan
12887 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012888 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070012889 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012890 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070012891 return -EBUSY;
12892 }
12893
Jeff Johnson295189b2012-06-20 16:38:30 -070012894 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
12895 {
12896 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080012897 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012898 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012899 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012900 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
12901 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012902 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012903 "%s: MAX TM Level Scan not allowed", __func__);
12904 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012905 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012906 }
12907 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
12908
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012909 /* Check if scan is allowed at this point of time.
12910 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012911 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012912 {
12913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
12914 return -EBUSY;
12915 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012916
Jeff Johnson295189b2012-06-20 16:38:30 -070012917 vos_mem_zero( &scanRequest, sizeof(scanRequest));
12918
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012919 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
12920 * Becasue of this, driver is assuming that this is not wildcard scan and so
12921 * is not aging out the scan results.
12922 */
12923 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070012924 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012925 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012926 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012927
12928 if ((request->ssids) && (0 < request->n_ssids))
12929 {
12930 tCsrSSIDInfo *SsidInfo;
12931 int j;
12932 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
12933 /* Allocate num_ssid tCsrSSIDInfo structure */
12934 SsidInfo = scanRequest.SSIDs.SSIDList =
12935 ( tCsrSSIDInfo *)vos_mem_malloc(
12936 request->n_ssids*sizeof(tCsrSSIDInfo));
12937
12938 if(NULL == scanRequest.SSIDs.SSIDList)
12939 {
12940 hddLog(VOS_TRACE_LEVEL_ERROR,
12941 "%s: memory alloc failed SSIDInfo buffer", __func__);
12942 return -ENOMEM;
12943 }
12944
12945 /* copy all the ssid's and their length */
12946 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
12947 {
12948 /* get the ssid length */
12949 SsidInfo->SSID.length = request->ssids[j].ssid_len;
12950 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
12951 SsidInfo->SSID.length);
12952 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
12953 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
12954 j, SsidInfo->SSID.ssId);
12955 }
12956 /* set the scan type to active */
12957 scanRequest.scanType = eSIR_ACTIVE_SCAN;
12958 }
12959 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012960 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012961 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12962 TRACE_CODE_HDD_CFG80211_SCAN,
12963 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070012964 /* set the scan type to active */
12965 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070012966 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012967 else
12968 {
12969 /*Set the scan type to default type, in this case it is ACTIVE*/
12970 scanRequest.scanType = pScanInfo->scan_mode;
12971 }
12972 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
12973 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070012974
12975 /* set BSSType to default type */
12976 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
12977
12978 /*TODO: scan the requested channels only*/
12979
12980 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012981 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070012982 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012983 hddLog(VOS_TRACE_LEVEL_WARN,
12984 "No of Scan Channels exceeded limit: %d", request->n_channels);
12985 request->n_channels = MAX_CHANNEL;
12986 }
12987
12988 hddLog(VOS_TRACE_LEVEL_INFO,
12989 "No of Scan Channels: %d", request->n_channels);
12990
12991
12992 if( request->n_channels )
12993 {
12994 char chList [(request->n_channels*5)+1];
12995 int len;
12996 channelList = vos_mem_malloc( request->n_channels );
12997 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053012998 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012999 hddLog(VOS_TRACE_LEVEL_ERROR,
13000 "%s: memory alloc failed channelList", __func__);
13001 status = -ENOMEM;
13002 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053013003 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013004
13005 for( i = 0, len = 0; i < request->n_channels ; i++ )
13006 {
13007 channelList[i] = request->channels[i]->hw_value;
13008 len += snprintf(chList+len, 5, "%d ", channelList[i]);
13009 }
13010
Nirav Shah20ac06f2013-12-12 18:14:06 +053013011 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013012 "Channel-List: %s ", chList);
13013 }
c_hpothu53512302014-04-15 18:49:53 +053013014
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013015 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13016 scanRequest.ChannelInfo.ChannelList = channelList;
13017
13018 /* set requestType to full scan */
13019 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13020
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013021 /* if there is back to back scan happening in driver with in
13022 * nDeferScanTimeInterval interval driver should defer new scan request
13023 * and should provide last cached scan results instead of new channel list.
13024 * This rule is not applicable if scan is p2p scan.
13025 * This condition will work only in case when last request no of channels
13026 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013027 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013028 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013029 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013030
Sushant Kaushik86592172015-04-27 16:35:03 +053013031 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13032 /* if wps ie is NULL , then only defer scan */
13033 if ( pWpsIe == NULL &&
13034 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013035 {
13036 if ( pScanInfo->last_scan_timestamp !=0 &&
13037 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13038 {
13039 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13040 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13041 vos_mem_compare(pScanInfo->last_scan_channelList,
13042 channelList, pScanInfo->last_scan_numChannels))
13043 {
13044 hddLog(VOS_TRACE_LEVEL_WARN,
13045 " New and old station scan time differ is less then %u",
13046 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13047
13048 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013049 pAdapter);
13050
Agarwal Ashish57e84372014-12-05 18:26:53 +053013051 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013052 "Return old cached scan as all channels and no of channels are same");
13053
Agarwal Ashish57e84372014-12-05 18:26:53 +053013054 if (0 > ret)
13055 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013056
Agarwal Ashish57e84372014-12-05 18:26:53 +053013057 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013058
13059 status = eHAL_STATUS_SUCCESS;
13060 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013061 }
13062 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013063 }
13064
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013065 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13066 * search (Flush on both full scan and social scan but not on single
13067 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13068 */
13069
13070 /* Supplicant does single channel scan after 8-way handshake
13071 * and in that case driver shoudnt flush scan results. If
13072 * driver flushes the scan results here and unfortunately if
13073 * the AP doesnt respond to our probe req then association
13074 * fails which is not desired
13075 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013076 if ((request->n_ssids == 1)
13077 && (request->ssids != NULL)
13078 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13079 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013080
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013081 if( is_p2p_scan ||
13082 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013083 {
13084 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13085 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13086 pAdapter->sessionId );
13087 }
13088
13089 if( request->ie_len )
13090 {
13091 /* save this for future association (join requires this) */
13092 /*TODO: Array needs to be converted to dynamic allocation,
13093 * as multiple ie.s can be sent in cfg80211_scan_request structure
13094 * CR 597966
13095 */
13096 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13097 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13098 pScanInfo->scanAddIE.length = request->ie_len;
13099
13100 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13101 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13102 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013103 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013104 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013105 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013106 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13107 memcpy( pwextBuf->roamProfile.addIEScan,
13108 request->ie, request->ie_len);
13109 }
13110 else
13111 {
13112 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13113 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013114 }
13115
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013116 }
13117 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13118 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13119
13120 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13121 request->ie_len);
13122 if (pP2pIe != NULL)
13123 {
13124#ifdef WLAN_FEATURE_P2P_DEBUG
13125 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13126 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13127 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013128 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013129 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13130 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13131 "Go nego completed to Connection is started");
13132 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13133 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013134 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013135 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13136 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013137 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013138 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13139 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13140 "Disconnected state to Connection is started");
13141 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13142 "for 4way Handshake");
13143 }
13144#endif
13145
13146 /* no_cck will be set during p2p find to disable 11b rates */
13147 if(TRUE == request->no_cck)
13148 {
13149 hddLog(VOS_TRACE_LEVEL_INFO,
13150 "%s: This is a P2P Search", __func__);
13151 scanRequest.p2pSearch = 1;
13152
13153 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013154 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013155 /* set requestType to P2P Discovery */
13156 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13157 }
13158
13159 /*
13160 Skip Dfs Channel in case of P2P Search
13161 if it is set in ini file
13162 */
13163 if(cfg_param->skipDfsChnlInP2pSearch)
13164 {
13165 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013166 }
13167 else
13168 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013169 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013170 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013171
Agarwal Ashish4f616132013-12-30 23:32:50 +053013172 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013173 }
13174 }
13175
13176 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13177
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013178#ifdef FEATURE_WLAN_TDLS
13179 /* if tdls disagree scan right now, return immediately.
13180 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13181 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13182 */
13183 status = wlan_hdd_tdls_scan_callback (pAdapter,
13184 wiphy,
13185#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13186 dev,
13187#endif
13188 request);
13189 if(status <= 0)
13190 {
13191 if(!status)
13192 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13193 "scan rejected %d", __func__, status);
13194 else
13195 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13196 __func__, status);
13197
13198 return status;
13199 }
13200#endif
13201
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013202 /* acquire the wakelock to avoid the apps suspend during the scan. To
13203 * address the following issues.
13204 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13205 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13206 * for long time, this result in apps running at full power for long time.
13207 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13208 * be stuck in full power because of resume BMPS
13209 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013210 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013211
Nirav Shah20ac06f2013-12-12 18:14:06 +053013212 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13213 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013214 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13215 scanRequest.requestType, scanRequest.scanType,
13216 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013217 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13218
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013219 if (pHddCtx->spoofMacAddr.isEnabled &&
13220 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013221 {
13222 hddLog(VOS_TRACE_LEVEL_INFO,
13223 "%s: MAC Spoofing enabled for current scan", __func__);
13224 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13225 * to fill TxBds for probe request during current scan
13226 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013227 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013228 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013229
13230 if(status != VOS_STATUS_SUCCESS)
13231 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013232 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013233 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013234#ifdef FEATURE_WLAN_TDLS
13235 wlan_hdd_tdls_scan_done_callback(pAdapter);
13236#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013237 goto free_mem;
13238 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013239 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013240 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013241 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013242 pAdapter->sessionId, &scanRequest, &scanId,
13243 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013244
Jeff Johnson295189b2012-06-20 16:38:30 -070013245 if (eHAL_STATUS_SUCCESS != status)
13246 {
13247 hddLog(VOS_TRACE_LEVEL_ERROR,
13248 "%s: sme_ScanRequest returned error %d", __func__, status);
13249 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013250 if(eHAL_STATUS_RESOURCES == status)
13251 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013252 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13253 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013254 status = -EBUSY;
13255 } else {
13256 status = -EIO;
13257 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013258 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013259
13260#ifdef FEATURE_WLAN_TDLS
13261 wlan_hdd_tdls_scan_done_callback(pAdapter);
13262#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013263 goto free_mem;
13264 }
13265
13266 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013267 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013268 pAdapter->request = request;
13269 pScanInfo->scanId = scanId;
13270
13271 complete(&pScanInfo->scan_req_completion_event);
13272
13273free_mem:
13274 if( scanRequest.SSIDs.SSIDList )
13275 {
13276 vos_mem_free(scanRequest.SSIDs.SSIDList);
13277 }
13278
13279 if( channelList )
13280 vos_mem_free( channelList );
13281
13282 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013283 return status;
13284}
13285
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013286int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13287#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13288 struct net_device *dev,
13289#endif
13290 struct cfg80211_scan_request *request)
13291{
13292 int ret;
13293
13294 vos_ssr_protect(__func__);
13295 ret = __wlan_hdd_cfg80211_scan(wiphy,
13296#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13297 dev,
13298#endif
13299 request);
13300 vos_ssr_unprotect(__func__);
13301
13302 return ret;
13303}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013304
13305void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13306{
13307 v_U8_t iniDot11Mode =
13308 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13309 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13310
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013311 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13312 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013313 switch ( iniDot11Mode )
13314 {
13315 case eHDD_DOT11_MODE_AUTO:
13316 case eHDD_DOT11_MODE_11ac:
13317 case eHDD_DOT11_MODE_11ac_ONLY:
13318#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013319 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13320 sme_IsFeatureSupportedByFW(DOT11AC) )
13321 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13322 else
13323 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013324#else
13325 hddDot11Mode = eHDD_DOT11_MODE_11n;
13326#endif
13327 break;
13328 case eHDD_DOT11_MODE_11n:
13329 case eHDD_DOT11_MODE_11n_ONLY:
13330 hddDot11Mode = eHDD_DOT11_MODE_11n;
13331 break;
13332 default:
13333 hddDot11Mode = iniDot11Mode;
13334 break;
13335 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013336#ifdef WLAN_FEATURE_AP_HT40_24G
13337 if (operationChannel > SIR_11B_CHANNEL_END)
13338#endif
13339 {
13340 /* This call decides required channel bonding mode */
13341 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013342 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13343 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013344 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013345}
13346
Jeff Johnson295189b2012-06-20 16:38:30 -070013347/*
13348 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013349 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013350 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013351int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013352 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13353 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013354{
13355 int status = 0;
13356 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013357 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013358 v_U32_t roamId;
13359 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013360 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013361 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013362
13363 ENTER();
13364
13365 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013366 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13367
13368 status = wlan_hdd_validate_context(pHddCtx);
13369 if (status)
13370 {
Yue Mae36e3552014-03-05 17:06:20 -080013371 return status;
13372 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013373
Jeff Johnson295189b2012-06-20 16:38:30 -070013374 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13375 {
13376 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13377 return -EINVAL;
13378 }
13379
13380 pRoamProfile = &pWextState->roamProfile;
13381
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013382 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013383 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013384 hdd_station_ctx_t *pHddStaCtx;
13385 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013386
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013387 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13388
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013389 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013390 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13391 {
13392 /*QoS not enabled in cfg file*/
13393 pRoamProfile->uapsd_mask = 0;
13394 }
13395 else
13396 {
13397 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013398 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013399 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13400 }
13401
13402 pRoamProfile->SSIDs.numOfSSIDs = 1;
13403 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13404 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013405 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013406 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13407 ssid, ssid_len);
13408
13409 if (bssid)
13410 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013411 pValidBssid = bssid;
13412 }
13413 else if (bssid_hint)
13414 {
13415 pValidBssid = bssid_hint;
13416 }
13417 if (pValidBssid)
13418 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013419 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013420 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013421 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013422 /* Save BSSID in seperate variable as well, as RoamProfile
13423 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013424 case of join failure we should send valid BSSID to supplicant
13425 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013426 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013427 WNI_CFG_BSSID_LEN);
13428 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013429 else
13430 {
13431 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13432 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013433
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013434 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13435 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013436 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13437 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013438 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013439 /*set gen ie*/
13440 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13441 /*set auth*/
13442 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13443 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013444#ifdef FEATURE_WLAN_WAPI
13445 if (pAdapter->wapi_info.nWapiMode)
13446 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013447 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013448 switch (pAdapter->wapi_info.wapiAuthMode)
13449 {
13450 case WAPI_AUTH_MODE_PSK:
13451 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013452 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013453 pAdapter->wapi_info.wapiAuthMode);
13454 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13455 break;
13456 }
13457 case WAPI_AUTH_MODE_CERT:
13458 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013459 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013460 pAdapter->wapi_info.wapiAuthMode);
13461 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13462 break;
13463 }
13464 } // End of switch
13465 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13466 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13467 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013468 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013469 pRoamProfile->AuthType.numEntries = 1;
13470 pRoamProfile->EncryptionType.numEntries = 1;
13471 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13472 pRoamProfile->mcEncryptionType.numEntries = 1;
13473 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13474 }
13475 }
13476#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013477#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013478 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013479 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13480 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13481 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013482 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13483 sizeof (tSirGtkOffloadParams));
13484 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013485 }
13486#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013487 pRoamProfile->csrPersona = pAdapter->device_mode;
13488
Jeff Johnson32d95a32012-09-10 13:15:23 -070013489 if( operatingChannel )
13490 {
13491 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13492 pRoamProfile->ChannelInfo.numOfChannels = 1;
13493 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013494 else
13495 {
13496 pRoamProfile->ChannelInfo.ChannelList = NULL;
13497 pRoamProfile->ChannelInfo.numOfChannels = 0;
13498 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013499 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13500 {
13501 hdd_select_cbmode(pAdapter,operatingChannel);
13502 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013503
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013504 /*
13505 * Change conn_state to connecting before sme_RoamConnect(),
13506 * because sme_RoamConnect() has a direct path to call
13507 * hdd_smeRoamCallback(), which will change the conn_state
13508 * If direct path, conn_state will be accordingly changed
13509 * to NotConnected or Associated by either
13510 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13511 * in sme_RoamCallback()
13512 * if sme_RomConnect is to be queued,
13513 * Connecting state will remain until it is completed.
13514 * If connection state is not changed,
13515 * connection state will remain in eConnectionState_NotConnected state.
13516 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13517 * if conn state is eConnectionState_NotConnected.
13518 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13519 * informed of connect result indication which is an issue.
13520 */
13521
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013522 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13523 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013524 {
13525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013526 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013527 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13528 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013529 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013530 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013531 pAdapter->sessionId, pRoamProfile, &roamId);
13532
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013533 if ((eHAL_STATUS_SUCCESS != status) &&
13534 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13535 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013536
13537 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013538 hddLog(VOS_TRACE_LEVEL_ERROR,
13539 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13540 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013541 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013542 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013543 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013544 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013545
13546 pRoamProfile->ChannelInfo.ChannelList = NULL;
13547 pRoamProfile->ChannelInfo.numOfChannels = 0;
13548
Jeff Johnson295189b2012-06-20 16:38:30 -070013549 }
13550 else
13551 {
13552 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13553 return -EINVAL;
13554 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013555 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013556 return status;
13557}
13558
13559/*
13560 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
13561 * This function is used to set the authentication type (OPEN/SHARED).
13562 *
13563 */
13564static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
13565 enum nl80211_auth_type auth_type)
13566{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013567 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013568 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13569
13570 ENTER();
13571
13572 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013573 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070013574 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013575 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013576 hddLog(VOS_TRACE_LEVEL_INFO,
13577 "%s: set authentication type to AUTOSWITCH", __func__);
13578 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
13579 break;
13580
13581 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013582#ifdef WLAN_FEATURE_VOWIFI_11R
13583 case NL80211_AUTHTYPE_FT:
13584#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013585 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013586 "%s: set authentication type to OPEN", __func__);
13587 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
13588 break;
13589
13590 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013591 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013592 "%s: set authentication type to SHARED", __func__);
13593 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
13594 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013595#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013596 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013597 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013598 "%s: set authentication type to CCKM WPA", __func__);
13599 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
13600 break;
13601#endif
13602
13603
13604 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013605 hddLog(VOS_TRACE_LEVEL_ERROR,
13606 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013607 auth_type);
13608 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
13609 return -EINVAL;
13610 }
13611
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013612 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013613 pHddStaCtx->conn_info.authType;
13614 return 0;
13615}
13616
13617/*
13618 * FUNCTION: wlan_hdd_set_akm_suite
13619 * This function is used to set the key mgmt type(PSK/8021x).
13620 *
13621 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013622static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013623 u32 key_mgmt
13624 )
13625{
13626 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13627 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053013628 /* Should be in ieee802_11_defs.h */
13629#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
13630#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070013631 /*set key mgmt type*/
13632 switch(key_mgmt)
13633 {
13634 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053013635 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013636#ifdef WLAN_FEATURE_VOWIFI_11R
13637 case WLAN_AKM_SUITE_FT_PSK:
13638#endif
13639 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070013640 __func__);
13641 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
13642 break;
13643
13644 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053013645 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013646#ifdef WLAN_FEATURE_VOWIFI_11R
13647 case WLAN_AKM_SUITE_FT_8021X:
13648#endif
13649 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070013650 __func__);
13651 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13652 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013653#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013654#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
13655#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
13656 case WLAN_AKM_SUITE_CCKM:
13657 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
13658 __func__);
13659 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
13660 break;
13661#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070013662#ifndef WLAN_AKM_SUITE_OSEN
13663#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
13664 case WLAN_AKM_SUITE_OSEN:
13665 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
13666 __func__);
13667 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13668 break;
13669#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013670
13671 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013672 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013673 __func__, key_mgmt);
13674 return -EINVAL;
13675
13676 }
13677 return 0;
13678}
13679
13680/*
13681 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013682 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070013683 * (NONE/WEP40/WEP104/TKIP/CCMP).
13684 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013685static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
13686 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070013687 bool ucast
13688 )
13689{
13690 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013691 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013692 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13693
13694 ENTER();
13695
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013696 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013697 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013698 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070013699 __func__, cipher);
13700 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13701 }
13702 else
13703 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013704
Jeff Johnson295189b2012-06-20 16:38:30 -070013705 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013706 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013707 {
13708 case IW_AUTH_CIPHER_NONE:
13709 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13710 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013711
Jeff Johnson295189b2012-06-20 16:38:30 -070013712 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013713 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070013714 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013715
Jeff Johnson295189b2012-06-20 16:38:30 -070013716 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013717 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070013718 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013719
Jeff Johnson295189b2012-06-20 16:38:30 -070013720 case WLAN_CIPHER_SUITE_TKIP:
13721 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
13722 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013723
Jeff Johnson295189b2012-06-20 16:38:30 -070013724 case WLAN_CIPHER_SUITE_CCMP:
13725 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13726 break;
13727#ifdef FEATURE_WLAN_WAPI
13728 case WLAN_CIPHER_SUITE_SMS4:
13729 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
13730 break;
13731#endif
13732
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013733#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013734 case WLAN_CIPHER_SUITE_KRK:
13735 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
13736 break;
13737#endif
13738 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013739 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013740 __func__, cipher);
13741 return -EOPNOTSUPP;
13742 }
13743 }
13744
13745 if (ucast)
13746 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013747 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013748 __func__, encryptionType);
13749 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13750 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013751 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013752 encryptionType;
13753 }
13754 else
13755 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013756 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013757 __func__, encryptionType);
13758 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
13759 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
13760 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
13761 }
13762
13763 return 0;
13764}
13765
13766
13767/*
13768 * FUNCTION: wlan_hdd_cfg80211_set_ie
13769 * This function is used to parse WPA/RSN IE's.
13770 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013771int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013772#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13773 const u8 *ie,
13774#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013775 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013776#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013777 size_t ie_len
13778 )
13779{
13780 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013781#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13782 const u8 *genie = ie;
13783#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013784 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013785#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013786 v_U16_t remLen = ie_len;
13787#ifdef FEATURE_WLAN_WAPI
13788 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
13789 u16 *tmp;
13790 v_U16_t akmsuiteCount;
13791 int *akmlist;
13792#endif
13793 ENTER();
13794
13795 /* clear previous assocAddIE */
13796 pWextState->assocAddIE.length = 0;
13797 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013798 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013799
13800 while (remLen >= 2)
13801 {
13802 v_U16_t eLen = 0;
13803 v_U8_t elementId;
13804 elementId = *genie++;
13805 eLen = *genie++;
13806 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013807
Arif Hussain6d2a3322013-11-17 19:50:10 -080013808 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070013809 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013810
13811 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070013812 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013813 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013814 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 -070013815 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013816 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013817 "%s: Invalid WPA IE", __func__);
13818 return -EINVAL;
13819 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013820 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070013821 {
13822 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013823 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013824 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013825
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013826 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013827 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013828 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
13829 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013830 VOS_ASSERT(0);
13831 return -ENOMEM;
13832 }
13833 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13834 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13835 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013836
Jeff Johnson295189b2012-06-20 16:38:30 -070013837 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
13838 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13839 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13840 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013841 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
13842 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013843 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
13844 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
13845 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
13846 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
13847 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
13848 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013849 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053013850 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013851 {
13852 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013853 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013854 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013855
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013856 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013857 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013858 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13859 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013860 VOS_ASSERT(0);
13861 return -ENOMEM;
13862 }
13863 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13864 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13865 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013866
Jeff Johnson295189b2012-06-20 16:38:30 -070013867 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13868 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13869 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013870#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013871 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
13872 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013873 /*Consider WFD IE, only for P2P Client */
13874 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
13875 {
13876 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013877 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013878 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013879
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013880 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013881 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013882 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13883 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013884 VOS_ASSERT(0);
13885 return -ENOMEM;
13886 }
13887 // WFD IE is saved to Additional IE ; it should be accumulated to handle
13888 // WPS IE + P2P IE + WFD IE
13889 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13890 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013891
Jeff Johnson295189b2012-06-20 16:38:30 -070013892 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13893 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13894 }
13895#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013896 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013897 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013898 HS20_OUI_TYPE_SIZE)) )
13899 {
13900 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013901 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013902 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013903
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013904 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013905 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013906 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13907 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013908 VOS_ASSERT(0);
13909 return -ENOMEM;
13910 }
13911 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13912 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013913
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013914 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13915 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13916 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013917 /* Appending OSEN Information Element in Assiciation Request */
13918 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
13919 OSEN_OUI_TYPE_SIZE)) )
13920 {
13921 v_U16_t curAddIELen = pWextState->assocAddIE.length;
13922 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
13923 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013924
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013925 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013926 {
13927 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13928 "Need bigger buffer space");
13929 VOS_ASSERT(0);
13930 return -ENOMEM;
13931 }
13932 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13933 pWextState->assocAddIE.length += eLen + 2;
13934
13935 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
13936 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13937 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13938 }
13939
Abhishek Singh4322e622015-06-10 15:42:54 +053013940 /* Update only for WPA IE */
13941 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
13942 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070013943
13944 /* populating as ADDIE in beacon frames */
13945 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013946 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070013947 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
13948 {
13949 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
13950 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
13951 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
13952 {
13953 hddLog(LOGE,
13954 "Coldn't pass "
13955 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
13956 }
13957 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
13958 else
13959 hddLog(LOGE,
13960 "Could not pass on "
13961 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
13962
13963 /* IBSS mode doesn't contain params->proberesp_ies still
13964 beaconIE's need to be populated in probe response frames */
13965 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
13966 {
13967 u16 rem_probe_resp_ie_len = eLen + 2;
13968 u8 probe_rsp_ie_len[3] = {0};
13969 u8 counter = 0;
13970
13971 /* Check Probe Resp Length if it is greater then 255 then
13972 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
13973 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
13974 not able Store More then 255 bytes into One Variable */
13975
13976 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
13977 {
13978 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
13979 {
13980 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
13981 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
13982 }
13983 else
13984 {
13985 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
13986 rem_probe_resp_ie_len = 0;
13987 }
13988 }
13989
13990 rem_probe_resp_ie_len = 0;
13991
13992 if (probe_rsp_ie_len[0] > 0)
13993 {
13994 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
13995 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
13996 (tANI_U8*)(genie - 2),
13997 probe_rsp_ie_len[0], NULL,
13998 eANI_BOOLEAN_FALSE)
13999 == eHAL_STATUS_FAILURE)
14000 {
14001 hddLog(LOGE,
14002 "Could not pass"
14003 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
14004 }
14005 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
14006 }
14007
14008 if (probe_rsp_ie_len[1] > 0)
14009 {
14010 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14011 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
14012 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14013 probe_rsp_ie_len[1], NULL,
14014 eANI_BOOLEAN_FALSE)
14015 == eHAL_STATUS_FAILURE)
14016 {
14017 hddLog(LOGE,
14018 "Could not pass"
14019 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14020 }
14021 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14022 }
14023
14024 if (probe_rsp_ie_len[2] > 0)
14025 {
14026 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14027 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14028 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14029 probe_rsp_ie_len[2], NULL,
14030 eANI_BOOLEAN_FALSE)
14031 == eHAL_STATUS_FAILURE)
14032 {
14033 hddLog(LOGE,
14034 "Could not pass"
14035 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14036 }
14037 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14038 }
14039
14040 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14041 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14042 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14043 {
14044 hddLog(LOGE,
14045 "Could not pass"
14046 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14047 }
14048 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014049 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014050 break;
14051 case DOT11F_EID_RSN:
14052 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14053 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14054 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14055 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14056 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14057 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014058
14059 /* Appending Extended Capabilities with Interworking bit set
14060 * in Assoc Req.
14061 *
14062 * In assoc req this EXT Cap will only be taken into account if
14063 * interworkingService bit is set to 1. Currently
14064 * driver is only interested in interworkingService capability
14065 * from supplicant. If in future any other EXT Cap info is
14066 * required from supplicat, it needs to be handled while
14067 * sending Assoc Req in LIM.
14068 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014069 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014070 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014071 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014072 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014073 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014074
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014075 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014076 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014077 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14078 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014079 VOS_ASSERT(0);
14080 return -ENOMEM;
14081 }
14082 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14083 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014084
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014085 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14086 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14087 break;
14088 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014089#ifdef FEATURE_WLAN_WAPI
14090 case WLAN_EID_WAPI:
14091 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014092 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014093 pAdapter->wapi_info.nWapiMode);
14094 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014095 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014096 akmsuiteCount = WPA_GET_LE16(tmp);
14097 tmp = tmp + 1;
14098 akmlist = (int *)(tmp);
14099 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14100 {
14101 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14102 }
14103 else
14104 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014105 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014106 VOS_ASSERT(0);
14107 return -EINVAL;
14108 }
14109
14110 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14111 {
14112 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014113 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014114 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014115 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014116 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014117 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014118 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014119 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014120 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14121 }
14122 break;
14123#endif
14124 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014125 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014126 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014127 /* when Unknown IE is received we should break and continue
14128 * to the next IE in the buffer instead we were returning
14129 * so changing this to break */
14130 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014131 }
14132 genie += eLen;
14133 remLen -= eLen;
14134 }
14135 EXIT();
14136 return 0;
14137}
14138
14139/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014140 * FUNCTION: hdd_isWPAIEPresent
14141 * Parse the received IE to find the WPA IE
14142 *
14143 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014144static bool hdd_isWPAIEPresent(
14145#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14146 const u8 *ie,
14147#else
14148 u8 *ie,
14149#endif
14150 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014151{
14152 v_U8_t eLen = 0;
14153 v_U16_t remLen = ie_len;
14154 v_U8_t elementId = 0;
14155
14156 while (remLen >= 2)
14157 {
14158 elementId = *ie++;
14159 eLen = *ie++;
14160 remLen -= 2;
14161 if (eLen > remLen)
14162 {
14163 hddLog(VOS_TRACE_LEVEL_ERROR,
14164 "%s: IE length is wrong %d", __func__, eLen);
14165 return FALSE;
14166 }
14167 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14168 {
14169 /* OUI - 0x00 0X50 0XF2
14170 WPA Information Element - 0x01
14171 WPA version - 0x01*/
14172 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14173 return TRUE;
14174 }
14175 ie += eLen;
14176 remLen -= eLen;
14177 }
14178 return FALSE;
14179}
14180
14181/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014182 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014183 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014184 * parameters during connect operation.
14185 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014186int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014187 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014188 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014189{
14190 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014191 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014192 ENTER();
14193
14194 /*set wpa version*/
14195 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14196
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014197 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014198 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014199 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014200 {
14201 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14202 }
14203 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14204 {
14205 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14206 }
14207 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014208
14209 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014210 pWextState->wpaVersion);
14211
14212 /*set authentication type*/
14213 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14214
14215 if (0 > status)
14216 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014217 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014218 "%s: failed to set authentication type ", __func__);
14219 return status;
14220 }
14221
14222 /*set key mgmt type*/
14223 if (req->crypto.n_akm_suites)
14224 {
14225 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14226 if (0 > status)
14227 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014228 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014229 __func__);
14230 return status;
14231 }
14232 }
14233
14234 /*set pairwise cipher type*/
14235 if (req->crypto.n_ciphers_pairwise)
14236 {
14237 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14238 req->crypto.ciphers_pairwise[0], true);
14239 if (0 > status)
14240 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014241 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014242 "%s: failed to set unicast cipher type", __func__);
14243 return status;
14244 }
14245 }
14246 else
14247 {
14248 /*Reset previous cipher suite to none*/
14249 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14250 if (0 > status)
14251 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014252 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014253 "%s: failed to set unicast cipher type", __func__);
14254 return status;
14255 }
14256 }
14257
14258 /*set group cipher type*/
14259 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14260 false);
14261
14262 if (0 > status)
14263 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014264 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014265 __func__);
14266 return status;
14267 }
14268
Chet Lanctot186b5732013-03-18 10:26:30 -070014269#ifdef WLAN_FEATURE_11W
14270 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14271#endif
14272
Jeff Johnson295189b2012-06-20 16:38:30 -070014273 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14274 if (req->ie_len)
14275 {
14276 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14277 if ( 0 > status)
14278 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014279 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014280 __func__);
14281 return status;
14282 }
14283 }
14284
14285 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014286 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014287 {
14288 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14289 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14290 )
14291 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014292 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014293 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14294 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014295 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014296 __func__);
14297 return -EOPNOTSUPP;
14298 }
14299 else
14300 {
14301 u8 key_len = req->key_len;
14302 u8 key_idx = req->key_idx;
14303
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014304 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014305 && (CSR_MAX_NUM_KEY > key_idx)
14306 )
14307 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014308 hddLog(VOS_TRACE_LEVEL_INFO,
14309 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014310 __func__, key_idx, key_len);
14311 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014312 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014313 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014314 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014315 (u8)key_len;
14316 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14317 }
14318 }
14319 }
14320 }
14321
14322 return status;
14323}
14324
14325/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014326 * FUNCTION: wlan_hdd_try_disconnect
14327 * This function is used to disconnect from previous
14328 * connection
14329 */
14330static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14331{
14332 long ret = 0;
14333 hdd_station_ctx_t *pHddStaCtx;
14334 eMib_dot11DesiredBssType connectedBssType;
14335
14336 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14337
14338 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14339
14340 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14341 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
14342 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14343 {
Abhishek Singhf7962582015-10-23 10:54:06 +053014344 hdd_connSetConnectionState(pHddStaCtx,
14345 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014346 /* Issue disconnect to CSR */
14347 INIT_COMPLETION(pAdapter->disconnect_comp_var);
14348 if( eHAL_STATUS_SUCCESS ==
14349 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14350 pAdapter->sessionId,
14351 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
14352 {
14353 ret = wait_for_completion_interruptible_timeout(
14354 &pAdapter->disconnect_comp_var,
14355 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
14356 if (0 >= ret)
14357 {
14358 hddLog(LOGE, FL("Failed to receive disconnect event"));
14359 return -EALREADY;
14360 }
14361 }
14362 }
14363 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14364 {
14365 ret = wait_for_completion_interruptible_timeout(
14366 &pAdapter->disconnect_comp_var,
14367 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
14368 if (0 >= ret)
14369 {
14370 hddLog(LOGE, FL("Failed to receive disconnect event"));
14371 return -EALREADY;
14372 }
14373 }
14374
14375 return 0;
14376}
14377
14378/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014379 * FUNCTION: __wlan_hdd_cfg80211_connect
14380 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014381 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014382static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014383 struct net_device *ndev,
14384 struct cfg80211_connect_params *req
14385 )
14386{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014387 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014388 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014389 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014390 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014391
14392 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014393
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014394 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14395 TRACE_CODE_HDD_CFG80211_CONNECT,
14396 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014397 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014398 "%s: device_mode = %s (%d)", __func__,
14399 hdd_device_modetoString(pAdapter->device_mode),
14400 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014401
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014402 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014403 if (!pHddCtx)
14404 {
14405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14406 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014407 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014408 }
14409
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014410 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014411 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014412 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014413 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014414 }
14415
Agarwal Ashish51325b52014-06-16 16:50:49 +053014416
Jeff Johnson295189b2012-06-20 16:38:30 -070014417#ifdef WLAN_BTAMP_FEATURE
14418 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014419 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014420 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014421 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014422 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014423 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014424 }
14425#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014426
14427 //If Device Mode is Station Concurrent Sessions Exit BMps
14428 //P2P Mode will be taken care in Open/close adapter
14429 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014430 (vos_concurrent_open_sessions_running())) {
14431 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14432 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014433 }
14434
14435 /*Try disconnecting if already in connected state*/
14436 status = wlan_hdd_try_disconnect(pAdapter);
14437 if ( 0 > status)
14438 {
14439 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14440 " connection"));
14441 return -EALREADY;
14442 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053014443 /* Check for max concurrent connections after doing disconnect if any*/
14444 if (vos_max_concurrent_connections_reached()) {
14445 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14446 return -ECONNREFUSED;
14447 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014448
Jeff Johnson295189b2012-06-20 16:38:30 -070014449 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014450 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014451
14452 if ( 0 > status)
14453 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014454 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014455 __func__);
14456 return status;
14457 }
Mohit Khanna765234a2012-09-11 15:08:35 -070014458 if ( req->channel )
14459 {
14460 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14461 req->ssid_len, req->bssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014462 req->bssid_hint,
Mohit Khanna765234a2012-09-11 15:08:35 -070014463 req->channel->hw_value);
14464 }
14465 else
14466 {
14467 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014468 req->ssid_len, req->bssid,
14469 req->bssid_hint, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070014470 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014471
Sushant Kaushikd7083982015-03-18 14:33:24 +053014472 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014473 {
14474 //ReEnable BMPS if disabled
14475 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
14476 (NULL != pHddCtx))
14477 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053014478 if (pHddCtx->hdd_wlan_suspended)
14479 {
14480 hdd_set_pwrparams(pHddCtx);
14481 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014482 //ReEnable Bmps and Imps back
14483 hdd_enable_bmps_imps(pHddCtx);
14484 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014485 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070014486 return status;
14487 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014488 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014489 EXIT();
14490 return status;
14491}
14492
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014493static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
14494 struct net_device *ndev,
14495 struct cfg80211_connect_params *req)
14496{
14497 int ret;
14498 vos_ssr_protect(__func__);
14499 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
14500 vos_ssr_unprotect(__func__);
14501
14502 return ret;
14503}
Jeff Johnson295189b2012-06-20 16:38:30 -070014504
14505/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014506 * FUNCTION: wlan_hdd_disconnect
14507 * This function is used to issue a disconnect request to SME
14508 */
14509int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
14510{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014511 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014512 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014513 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014514 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014515
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014516 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014517
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014518 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014519 if (0 != status)
14520 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014521 return status;
14522 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053014523 /* Indicate sme of disconnect so that in progress connection or preauth
14524 * can be aborted
14525 */
14526 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053014527 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014528 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014529
Agarwal Ashish47d18112014-08-04 19:55:07 +053014530 /* Need to apply spin lock before decreasing active sessions
14531 * as there can be chance for double decrement if context switch
14532 * Calls hdd_DisConnectHandler.
14533 */
14534
14535 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014536 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14537 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014538 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14539 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053014540 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
14541 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014542
Abhishek Singhf4669da2014-05-26 15:07:49 +053014543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053014544 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
14545
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014546 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014547
Mihir Shete182a0b22014-08-18 16:08:48 +053014548 /*
14549 * stop tx queues before deleting STA/BSS context from the firmware.
14550 * tx has to be disabled because the firmware can get busy dropping
14551 * the tx frames after BSS/STA has been deleted and will not send
14552 * back a response resulting in WDI timeout
14553 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053014554 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053014555 netif_tx_disable(pAdapter->dev);
14556 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014557
Mihir Shete182a0b22014-08-18 16:08:48 +053014558 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014559 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14560 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014561 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
14562 {
14563 hddLog(VOS_TRACE_LEVEL_INFO,
14564 FL("status = %d, already disconnected"),
14565 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014566
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014567 }
14568 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014569 {
14570 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014571 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014572 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014573 result = -EINVAL;
14574 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014575 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014576 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014577 &pAdapter->disconnect_comp_var,
14578 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014579 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014580 {
14581 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014582 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014583 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014584 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014585 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014586 {
14587 hddLog(VOS_TRACE_LEVEL_ERROR,
14588 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014589 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014590 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014591disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14593 FL("Set HDD connState to eConnectionState_NotConnected"));
14594 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14595
Abhishek Singh087de602015-10-21 17:18:55 +053014596#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
14597 /* Sending disconnect event to userspace for kernel version < 3.11
14598 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
14599 */
14600 hddLog(LOG1, FL("Send disconnected event to userspace"));
14601 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
14602 NULL, 0, GFP_KERNEL);
14603#endif
14604
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014605 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014606 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014607}
14608
14609
14610/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014611 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070014612 * This function is used to issue a disconnect request to SME
14613 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014614static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014615 struct net_device *dev,
14616 u16 reason
14617 )
14618{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014619 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014620 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014621 tCsrRoamProfile *pRoamProfile;
14622 hdd_station_ctx_t *pHddStaCtx;
14623 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014624#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014625 tANI_U8 staIdx;
14626#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014627
Jeff Johnson295189b2012-06-20 16:38:30 -070014628 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014629
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014630 if (!pAdapter) {
14631 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14632 return -EINVAL;
14633 }
14634
14635 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14636 if (!pHddStaCtx) {
14637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
14638 return -EINVAL;
14639 }
14640
14641 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14642 status = wlan_hdd_validate_context(pHddCtx);
14643 if (0 != status)
14644 {
14645 return status;
14646 }
14647
14648 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
14649
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014650 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14651 TRACE_CODE_HDD_CFG80211_DISCONNECT,
14652 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014653 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
14654 __func__, hdd_device_modetoString(pAdapter->device_mode),
14655 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014656
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014657 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
14658 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070014659
Jeff Johnson295189b2012-06-20 16:38:30 -070014660 if (NULL != pRoamProfile)
14661 {
14662 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014663 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
14664 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070014665 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014666 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070014667 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014668 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014669 switch(reason)
14670 {
14671 case WLAN_REASON_MIC_FAILURE:
14672 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
14673 break;
14674
14675 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
14676 case WLAN_REASON_DISASSOC_AP_BUSY:
14677 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
14678 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
14679 break;
14680
14681 case WLAN_REASON_PREV_AUTH_NOT_VALID:
14682 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053014683 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070014684 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
14685 break;
14686
Jeff Johnson295189b2012-06-20 16:38:30 -070014687 default:
14688 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
14689 break;
14690 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014691 pScanInfo = &pHddCtx->scan_info;
14692 if (pScanInfo->mScanPending)
14693 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014694 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014695 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014696 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014697 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014698 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053014699 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014700#ifdef FEATURE_WLAN_TDLS
14701 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014702 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014703 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014704 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
14705 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014706 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014707 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014708 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014710 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014711 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014712 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014713 status = sme_DeleteTdlsPeerSta(
14714 WLAN_HDD_GET_HAL_CTX(pAdapter),
14715 pAdapter->sessionId,
14716 mac);
14717 if (status != eHAL_STATUS_SUCCESS) {
14718 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
14719 return -EPERM;
14720 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014721 }
14722 }
14723#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014724 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014725 status = wlan_hdd_disconnect(pAdapter, reasonCode);
14726 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070014727 {
14728 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014729 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014730 __func__, (int)status );
14731 return -EINVAL;
14732 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014733 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014734 else
14735 {
14736 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
14737 "called while in %d state", __func__,
14738 pHddStaCtx->conn_info.connState);
14739 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014740 }
14741 else
14742 {
14743 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
14744 }
14745
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014746 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014747 return status;
14748}
14749
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014750static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
14751 struct net_device *dev,
14752 u16 reason
14753 )
14754{
14755 int ret;
14756 vos_ssr_protect(__func__);
14757 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
14758 vos_ssr_unprotect(__func__);
14759
14760 return ret;
14761}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014762
Jeff Johnson295189b2012-06-20 16:38:30 -070014763/*
14764 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014765 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014766 * settings in IBSS mode.
14767 */
14768static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014769 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014770 struct cfg80211_ibss_params *params
14771 )
14772{
14773 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014774 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014775 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14776 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014777
Jeff Johnson295189b2012-06-20 16:38:30 -070014778 ENTER();
14779
14780 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070014781 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070014782
14783 if (params->ie_len && ( NULL != params->ie) )
14784 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014785 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14786 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014787 {
14788 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14789 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14790 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014791 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014792 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014793 tDot11fIEWPA dot11WPAIE;
14794 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014795 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014796
Wilson Yang00256342013-10-10 23:13:38 -070014797 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014798 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14799 params->ie_len, DOT11F_EID_WPA);
14800 if ( NULL != ie )
14801 {
14802 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14803 // Unpack the WPA IE
14804 //Skip past the EID byte and length byte - and four byte WiFi OUI
14805 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
14806 &ie[2+4],
14807 ie[1] - 4,
14808 &dot11WPAIE);
14809 /*Extract the multicast cipher, the encType for unicast
14810 cipher for wpa-none is none*/
14811 encryptionType =
14812 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
14813 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014814 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014815
Jeff Johnson295189b2012-06-20 16:38:30 -070014816 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
14817
14818 if (0 > status)
14819 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014820 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014821 __func__);
14822 return status;
14823 }
14824 }
14825
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014826 pWextState->roamProfile.AuthType.authType[0] =
14827 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014828 eCSR_AUTH_TYPE_OPEN_SYSTEM;
14829
14830 if (params->privacy)
14831 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014832 /* Security enabled IBSS, At this time there is no information available
14833 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070014834 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014835 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070014836 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014837 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070014838 *enable privacy bit in beacons */
14839
14840 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
14841 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014842 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
14843 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070014844 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14845 pWextState->roamProfile.EncryptionType.numEntries = 1;
14846 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070014847 return status;
14848}
14849
14850/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014851 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014852 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070014853 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014854static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014855 struct net_device *dev,
14856 struct cfg80211_ibss_params *params
14857 )
14858{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014859 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014860 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14861 tCsrRoamProfile *pRoamProfile;
14862 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014863 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14864 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014865 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070014866
14867 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014868
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014869 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14870 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
14871 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014872 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014873 "%s: device_mode = %s (%d)", __func__,
14874 hdd_device_modetoString(pAdapter->device_mode),
14875 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014876
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014877 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014878 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014879 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014880 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014881 }
14882
14883 if (NULL == pWextState)
14884 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014885 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070014886 __func__);
14887 return -EIO;
14888 }
14889
Agarwal Ashish51325b52014-06-16 16:50:49 +053014890 if (vos_max_concurrent_connections_reached()) {
14891 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14892 return -ECONNREFUSED;
14893 }
14894
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014895 /*Try disconnecting if already in connected state*/
14896 status = wlan_hdd_try_disconnect(pAdapter);
14897 if ( 0 > status)
14898 {
14899 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14900 " IBSS connection"));
14901 return -EALREADY;
14902 }
14903
Jeff Johnson295189b2012-06-20 16:38:30 -070014904 pRoamProfile = &pWextState->roamProfile;
14905
14906 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
14907 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014908 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014909 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014910 return -EINVAL;
14911 }
14912
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014913 /* BSSID is provided by upper layers hence no need to AUTO generate */
14914 if (NULL != params->bssid) {
14915 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
14916 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
14917 hddLog (VOS_TRACE_LEVEL_ERROR,
14918 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
14919 return -EIO;
14920 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014921 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014922 }
krunal sonie9002db2013-11-25 14:24:17 -080014923 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
14924 {
14925 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
14926 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
14927 {
14928 hddLog (VOS_TRACE_LEVEL_ERROR,
14929 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
14930 return -EIO;
14931 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014932
14933 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080014934 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014935 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080014936 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014937
Jeff Johnson295189b2012-06-20 16:38:30 -070014938 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070014939 if (NULL !=
14940#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
14941 params->chandef.chan)
14942#else
14943 params->channel)
14944#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014945 {
14946 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014947 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14948 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
14949 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14950 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014951
14952 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014953 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070014954 ieee80211_frequency_to_channel(
14955#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
14956 params->chandef.chan->center_freq);
14957#else
14958 params->channel->center_freq);
14959#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014960
14961 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14962 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070014963 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014964 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
14965 __func__);
14966 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070014967 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014968
14969 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014970 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014971 if (channelNum == validChan[indx])
14972 {
14973 break;
14974 }
14975 }
14976 if (indx >= numChans)
14977 {
14978 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014979 __func__, channelNum);
14980 return -EINVAL;
14981 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014982 /* Set the Operational Channel */
14983 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
14984 channelNum);
14985 pRoamProfile->ChannelInfo.numOfChannels = 1;
14986 pHddStaCtx->conn_info.operationChannel = channelNum;
14987 pRoamProfile->ChannelInfo.ChannelList =
14988 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070014989 }
14990
14991 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014992 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070014993 if (status < 0)
14994 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014995 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070014996 __func__);
14997 return status;
14998 }
14999
15000 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015001 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053015002 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015003 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015004
15005 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015006 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015007
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015008 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015009 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015010}
15011
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015012static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
15013 struct net_device *dev,
15014 struct cfg80211_ibss_params *params
15015 )
15016{
15017 int ret = 0;
15018
15019 vos_ssr_protect(__func__);
15020 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15021 vos_ssr_unprotect(__func__);
15022
15023 return ret;
15024}
15025
Jeff Johnson295189b2012-06-20 16:38:30 -070015026/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015027 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015028 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015029 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015030static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015031 struct net_device *dev
15032 )
15033{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015034 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015035 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15036 tCsrRoamProfile *pRoamProfile;
15037 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015038 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015039
15040 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015041
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015042 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15043 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15044 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015045 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015046 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015047 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015048 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015049 }
15050
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015051 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15052 hdd_device_modetoString(pAdapter->device_mode),
15053 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015054 if (NULL == pWextState)
15055 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015056 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015057 __func__);
15058 return -EIO;
15059 }
15060
15061 pRoamProfile = &pWextState->roamProfile;
15062
15063 /* Issue disconnect only if interface type is set to IBSS */
15064 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15065 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015066 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015067 __func__);
15068 return -EINVAL;
15069 }
15070
15071 /* Issue Disconnect request */
15072 INIT_COMPLETION(pAdapter->disconnect_comp_var);
15073 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15074 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15075
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015076 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015077 return 0;
15078}
15079
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015080static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15081 struct net_device *dev
15082 )
15083{
15084 int ret = 0;
15085
15086 vos_ssr_protect(__func__);
15087 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15088 vos_ssr_unprotect(__func__);
15089
15090 return ret;
15091}
15092
Jeff Johnson295189b2012-06-20 16:38:30 -070015093/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015094 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015095 * This function is used to set the phy parameters
15096 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15097 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015098static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015099 u32 changed)
15100{
15101 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15102 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015103 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015104
15105 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015106
15107 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015108 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15109 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015110
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015111 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015112 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015113 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015114 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015115 }
15116
Jeff Johnson295189b2012-06-20 16:38:30 -070015117 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15118 {
15119 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15120 WNI_CFG_RTS_THRESHOLD_STAMAX :
15121 wiphy->rts_threshold;
15122
15123 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015124 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015125 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015126 hddLog(VOS_TRACE_LEVEL_ERROR,
15127 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015128 __func__, rts_threshold);
15129 return -EINVAL;
15130 }
15131
15132 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15133 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015134 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015135 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015136 hddLog(VOS_TRACE_LEVEL_ERROR,
15137 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015138 __func__, rts_threshold);
15139 return -EIO;
15140 }
15141
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015142 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015143 rts_threshold);
15144 }
15145
15146 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15147 {
15148 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15149 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15150 wiphy->frag_threshold;
15151
15152 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015153 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015154 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015155 hddLog(VOS_TRACE_LEVEL_ERROR,
15156 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015157 frag_threshold);
15158 return -EINVAL;
15159 }
15160
15161 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15162 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015163 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015164 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015165 hddLog(VOS_TRACE_LEVEL_ERROR,
15166 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015167 __func__, frag_threshold);
15168 return -EIO;
15169 }
15170
15171 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15172 frag_threshold);
15173 }
15174
15175 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15176 || (changed & WIPHY_PARAM_RETRY_LONG))
15177 {
15178 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15179 wiphy->retry_short :
15180 wiphy->retry_long;
15181
15182 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15183 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15184 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015185 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015186 __func__, retry_value);
15187 return -EINVAL;
15188 }
15189
15190 if (changed & WIPHY_PARAM_RETRY_SHORT)
15191 {
15192 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15193 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015194 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015195 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015196 hddLog(VOS_TRACE_LEVEL_ERROR,
15197 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015198 __func__, retry_value);
15199 return -EIO;
15200 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015201 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015202 __func__, retry_value);
15203 }
15204 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15205 {
15206 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15207 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015208 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015209 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015210 hddLog(VOS_TRACE_LEVEL_ERROR,
15211 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015212 __func__, retry_value);
15213 return -EIO;
15214 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015215 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015216 __func__, retry_value);
15217 }
15218 }
15219
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015220 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015221 return 0;
15222}
15223
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015224static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15225 u32 changed)
15226{
15227 int ret;
15228
15229 vos_ssr_protect(__func__);
15230 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15231 vos_ssr_unprotect(__func__);
15232
15233 return ret;
15234}
15235
Jeff Johnson295189b2012-06-20 16:38:30 -070015236/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015237 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015238 * This function is used to set the txpower
15239 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015240static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015241#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15242 struct wireless_dev *wdev,
15243#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015244#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015245 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015246#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015247 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015248#endif
15249 int dbm)
15250{
15251 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015252 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015253 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15254 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015255 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015256
15257 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015258
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015259 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15260 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15261 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015262 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015263 if (0 != status)
15264 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015265 return status;
15266 }
15267
15268 hHal = pHddCtx->hHal;
15269
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015270 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15271 dbm, ccmCfgSetCallback,
15272 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015273 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015274 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015275 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15276 return -EIO;
15277 }
15278
15279 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15280 dbm);
15281
15282 switch(type)
15283 {
15284 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15285 /* Fall through */
15286 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15287 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15288 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015289 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15290 __func__);
15291 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015292 }
15293 break;
15294 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015295 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015296 __func__);
15297 return -EOPNOTSUPP;
15298 break;
15299 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015300 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15301 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015302 return -EIO;
15303 }
15304
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015305 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015306 return 0;
15307}
15308
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015309static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15310#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15311 struct wireless_dev *wdev,
15312#endif
15313#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15314 enum tx_power_setting type,
15315#else
15316 enum nl80211_tx_power_setting type,
15317#endif
15318 int dbm)
15319{
15320 int ret;
15321 vos_ssr_protect(__func__);
15322 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15323#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15324 wdev,
15325#endif
15326#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15327 type,
15328#else
15329 type,
15330#endif
15331 dbm);
15332 vos_ssr_unprotect(__func__);
15333
15334 return ret;
15335}
15336
Jeff Johnson295189b2012-06-20 16:38:30 -070015337/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015338 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015339 * This function is used to read the txpower
15340 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015341static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015342#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15343 struct wireless_dev *wdev,
15344#endif
15345 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015346{
15347
15348 hdd_adapter_t *pAdapter;
15349 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015350 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015351
Jeff Johnsone7245742012-09-05 17:12:55 -070015352 ENTER();
15353
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015354 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015355 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015356 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015357 *dbm = 0;
15358 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015359 }
15360
Jeff Johnson295189b2012-06-20 16:38:30 -070015361 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15362 if (NULL == pAdapter)
15363 {
15364 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15365 return -ENOENT;
15366 }
15367
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015368 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15369 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15370 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015371 wlan_hdd_get_classAstats(pAdapter);
15372 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15373
Jeff Johnsone7245742012-09-05 17:12:55 -070015374 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015375 return 0;
15376}
15377
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015378static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15379#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15380 struct wireless_dev *wdev,
15381#endif
15382 int *dbm)
15383{
15384 int ret;
15385
15386 vos_ssr_protect(__func__);
15387 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15388#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15389 wdev,
15390#endif
15391 dbm);
15392 vos_ssr_unprotect(__func__);
15393
15394 return ret;
15395}
15396
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015397static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015398#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15399 const u8* mac,
15400#else
15401 u8* mac,
15402#endif
15403 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015404{
15405 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15406 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15407 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053015408 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015409
15410 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
15411 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070015412
15413 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
15414 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
15415 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
15416 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
15417 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
15418 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
15419 tANI_U16 maxRate = 0;
15420 tANI_U16 myRate;
15421 tANI_U16 currentRate = 0;
15422 tANI_U8 maxSpeedMCS = 0;
15423 tANI_U8 maxMCSIdx = 0;
15424 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053015425 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070015426 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015427 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015428
Leo Chang6f8870f2013-03-26 18:11:36 -070015429#ifdef WLAN_FEATURE_11AC
15430 tANI_U32 vht_mcs_map;
15431 eDataRate11ACMaxMcs vhtMaxMcs;
15432#endif /* WLAN_FEATURE_11AC */
15433
Jeff Johnsone7245742012-09-05 17:12:55 -070015434 ENTER();
15435
Jeff Johnson295189b2012-06-20 16:38:30 -070015436 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15437 (0 == ssidlen))
15438 {
15439 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
15440 " Invalid ssidlen, %d", __func__, ssidlen);
15441 /*To keep GUI happy*/
15442 return 0;
15443 }
15444
Mukul Sharma811205f2014-07-09 21:07:30 +053015445 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
15446 {
15447 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15448 "%s: Roaming in progress, so unable to proceed this request", __func__);
15449 return 0;
15450 }
15451
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015452 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015453 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015454 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015455 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015456 }
15457
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053015458 wlan_hdd_get_station_stats(pAdapter);
15459 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015460
Kiet Lam3b17fc82013-09-27 05:24:08 +053015461 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
15462 sinfo->filled |= STATION_INFO_SIGNAL;
15463
c_hpothu09f19542014-05-30 21:53:31 +053015464 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053015465 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
15466 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053015467 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053015468 {
15469 rate_flags = pAdapter->maxRateFlags;
15470 }
c_hpothu44ff4e02014-05-08 00:13:57 +053015471
Jeff Johnson295189b2012-06-20 16:38:30 -070015472 //convert to the UI units of 100kbps
15473 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
15474
15475#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070015476 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 -070015477 sinfo->signal,
15478 pCfg->reportMaxLinkSpeed,
15479 myRate,
15480 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015481 (int) pCfg->linkSpeedRssiMid,
15482 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070015483 (int) rate_flags,
15484 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070015485#endif //LINKSPEED_DEBUG_ENABLED
15486
15487 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
15488 {
15489 // we do not want to necessarily report the current speed
15490 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
15491 {
15492 // report the max possible speed
15493 rssidx = 0;
15494 }
15495 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
15496 {
15497 // report the max possible speed with RSSI scaling
15498 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
15499 {
15500 // report the max possible speed
15501 rssidx = 0;
15502 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015503 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070015504 {
15505 // report middle speed
15506 rssidx = 1;
15507 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015508 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
15509 {
15510 // report middle speed
15511 rssidx = 2;
15512 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015513 else
15514 {
15515 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015516 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070015517 }
15518 }
15519 else
15520 {
15521 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
15522 hddLog(VOS_TRACE_LEVEL_ERROR,
15523 "%s: Invalid value for reportMaxLinkSpeed: %u",
15524 __func__, pCfg->reportMaxLinkSpeed);
15525 rssidx = 0;
15526 }
15527
15528 maxRate = 0;
15529
15530 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015531 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
15532 OperationalRates, &ORLeng))
15533 {
15534 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15535 /*To keep GUI happy*/
15536 return 0;
15537 }
15538
Jeff Johnson295189b2012-06-20 16:38:30 -070015539 for (i = 0; i < ORLeng; i++)
15540 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015541 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015542 {
15543 /* Validate Rate Set */
15544 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
15545 {
15546 currentRate = supported_data_rate[j].supported_rate[rssidx];
15547 break;
15548 }
15549 }
15550 /* Update MAX rate */
15551 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15552 }
15553
15554 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015555 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
15556 ExtendedRates, &ERLeng))
15557 {
15558 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15559 /*To keep GUI happy*/
15560 return 0;
15561 }
15562
Jeff Johnson295189b2012-06-20 16:38:30 -070015563 for (i = 0; i < ERLeng; i++)
15564 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015565 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015566 {
15567 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
15568 {
15569 currentRate = supported_data_rate[j].supported_rate[rssidx];
15570 break;
15571 }
15572 }
15573 /* Update MAX rate */
15574 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15575 }
c_hpothu79aab322014-07-14 21:11:01 +053015576
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015577 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053015578 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015579 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053015580 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070015581 {
c_hpothu79aab322014-07-14 21:11:01 +053015582 if (rate_flags & eHAL_TX_RATE_VHT80)
15583 mode = 2;
15584 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
15585 mode = 1;
15586 else
15587 mode = 0;
15588
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015589 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
15590 MCSRates, &MCSLeng))
15591 {
15592 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15593 /*To keep GUI happy*/
15594 return 0;
15595 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015596 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070015597#ifdef WLAN_FEATURE_11AC
15598 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015599 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070015600 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015601 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015602 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070015603 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070015604 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015605 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015606 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015607 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070015608 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015609 maxMCSIdx = 7;
15610 }
15611 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
15612 {
15613 maxMCSIdx = 8;
15614 }
15615 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
15616 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015617 //VHT20 is supporting 0~8
15618 if (rate_flags & eHAL_TX_RATE_VHT20)
15619 maxMCSIdx = 8;
15620 else
15621 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070015622 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015623
c_hpothu79aab322014-07-14 21:11:01 +053015624 if (0 != rssidx)/*check for scaled */
15625 {
15626 //get middle rate MCS index if rssi=1/2
15627 for (i=0; i <= maxMCSIdx; i++)
15628 {
15629 if (sinfo->signal <= rssiMcsTbl[mode][i])
15630 {
15631 maxMCSIdx = i;
15632 break;
15633 }
15634 }
15635 }
15636
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015637 if (rate_flags & eHAL_TX_RATE_VHT80)
15638 {
15639 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
15640 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
15641 }
15642 else if (rate_flags & eHAL_TX_RATE_VHT40)
15643 {
15644 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
15645 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
15646 }
15647 else if (rate_flags & eHAL_TX_RATE_VHT20)
15648 {
15649 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
15650 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
15651 }
15652
Leo Chang6f8870f2013-03-26 18:11:36 -070015653 maxSpeedMCS = 1;
15654 if (currentRate > maxRate)
15655 {
15656 maxRate = currentRate;
15657 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015658
Leo Chang6f8870f2013-03-26 18:11:36 -070015659 }
15660 else
15661#endif /* WLAN_FEATURE_11AC */
15662 {
15663 if (rate_flags & eHAL_TX_RATE_HT40)
15664 {
15665 rateFlag |= 1;
15666 }
15667 if (rate_flags & eHAL_TX_RATE_SGI)
15668 {
15669 rateFlag |= 2;
15670 }
15671
Girish Gowli01abcee2014-07-31 20:18:55 +053015672 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053015673 if (rssidx == 1 || rssidx == 2)
15674 {
15675 //get middle rate MCS index if rssi=1/2
15676 for (i=0; i <= 7; i++)
15677 {
15678 if (sinfo->signal <= rssiMcsTbl[mode][i])
15679 {
15680 temp = i+1;
15681 break;
15682 }
15683 }
15684 }
c_hpothu79aab322014-07-14 21:11:01 +053015685
15686 for (i = 0; i < MCSLeng; i++)
15687 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015688 for (j = 0; j < temp; j++)
15689 {
15690 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
15691 {
15692 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015693 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015694 break;
15695 }
15696 }
15697 if ((j < temp) && (currentRate > maxRate))
15698 {
15699 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070015700 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015701 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015702 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015703 }
15704 }
15705
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015706 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
15707 {
15708 maxRate = myRate;
15709 maxSpeedMCS = 1;
15710 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15711 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015712 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053015713 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070015714 {
15715 maxRate = myRate;
15716 if (rate_flags & eHAL_TX_RATE_LEGACY)
15717 {
15718 maxSpeedMCS = 0;
15719 }
15720 else
15721 {
15722 maxSpeedMCS = 1;
15723 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15724 }
15725 }
15726
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015727 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070015728 {
15729 sinfo->txrate.legacy = maxRate;
15730#ifdef LINKSPEED_DEBUG_ENABLED
15731 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
15732#endif //LINKSPEED_DEBUG_ENABLED
15733 }
15734 else
15735 {
15736 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070015737#ifdef WLAN_FEATURE_11AC
15738 sinfo->txrate.nss = 1;
15739 if (rate_flags & eHAL_TX_RATE_VHT80)
15740 {
15741 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015742 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070015743 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015744 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070015745 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015746 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15747 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15748 }
15749 else if (rate_flags & eHAL_TX_RATE_VHT20)
15750 {
15751 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15752 }
15753#endif /* WLAN_FEATURE_11AC */
15754 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
15755 {
15756 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15757 if (rate_flags & eHAL_TX_RATE_HT40)
15758 {
15759 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15760 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015761 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015762 if (rate_flags & eHAL_TX_RATE_SGI)
15763 {
15764 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15765 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015766
Jeff Johnson295189b2012-06-20 16:38:30 -070015767#ifdef LINKSPEED_DEBUG_ENABLED
15768 pr_info("Reporting MCS rate %d flags %x\n",
15769 sinfo->txrate.mcs,
15770 sinfo->txrate.flags );
15771#endif //LINKSPEED_DEBUG_ENABLED
15772 }
15773 }
15774 else
15775 {
15776 // report current rate instead of max rate
15777
15778 if (rate_flags & eHAL_TX_RATE_LEGACY)
15779 {
15780 //provide to the UI in units of 100kbps
15781 sinfo->txrate.legacy = myRate;
15782#ifdef LINKSPEED_DEBUG_ENABLED
15783 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
15784#endif //LINKSPEED_DEBUG_ENABLED
15785 }
15786 else
15787 {
15788 //must be MCS
15789 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015790#ifdef WLAN_FEATURE_11AC
15791 sinfo->txrate.nss = 1;
15792 if (rate_flags & eHAL_TX_RATE_VHT80)
15793 {
15794 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15795 }
15796 else
15797#endif /* WLAN_FEATURE_11AC */
15798 {
15799 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15800 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015801 if (rate_flags & eHAL_TX_RATE_SGI)
15802 {
15803 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15804 }
15805 if (rate_flags & eHAL_TX_RATE_HT40)
15806 {
15807 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15808 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015809#ifdef WLAN_FEATURE_11AC
15810 else if (rate_flags & eHAL_TX_RATE_VHT80)
15811 {
15812 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
15813 }
15814#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070015815#ifdef LINKSPEED_DEBUG_ENABLED
15816 pr_info("Reporting actual MCS rate %d flags %x\n",
15817 sinfo->txrate.mcs,
15818 sinfo->txrate.flags );
15819#endif //LINKSPEED_DEBUG_ENABLED
15820 }
15821 }
15822 sinfo->filled |= STATION_INFO_TX_BITRATE;
15823
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070015824 sinfo->tx_packets =
15825 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
15826 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
15827 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
15828 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
15829
15830 sinfo->tx_retries =
15831 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
15832 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
15833 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
15834 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
15835
15836 sinfo->tx_failed =
15837 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
15838 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
15839 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
15840 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
15841
15842 sinfo->filled |=
15843 STATION_INFO_TX_PACKETS |
15844 STATION_INFO_TX_RETRIES |
15845 STATION_INFO_TX_FAILED;
15846
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015847 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15848 TRACE_CODE_HDD_CFG80211_GET_STA,
15849 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070015850 EXIT();
15851 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015852}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015853#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15854static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
15855 const u8* mac, struct station_info *sinfo)
15856#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015857static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
15858 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015859#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015860{
15861 int ret;
15862
15863 vos_ssr_protect(__func__);
15864 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
15865 vos_ssr_unprotect(__func__);
15866
15867 return ret;
15868}
15869
15870static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070015871 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070015872{
15873 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015874 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015875 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015876 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015877
Jeff Johnsone7245742012-09-05 17:12:55 -070015878 ENTER();
15879
Jeff Johnson295189b2012-06-20 16:38:30 -070015880 if (NULL == pAdapter)
15881 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015882 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015883 return -ENODEV;
15884 }
15885
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015886 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15887 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
15888 pAdapter->sessionId, timeout));
15889
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015890 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015891 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015892 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015893 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015894 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015895 }
15896
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015897 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
15898 (TRUE == pHddCtx->hdd_wlan_suspended) &&
15899 (pHddCtx->cfg_ini->fhostArpOffload) &&
15900 (eConnectionState_Associated ==
15901 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15902 {
Amar Singhald53568e2013-09-26 11:03:45 -070015903
15904 hddLog(VOS_TRACE_LEVEL_INFO,
15905 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053015906 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015907 if (!VOS_IS_STATUS_SUCCESS(vos_status))
15908 {
15909 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015910 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015911 __func__, vos_status);
15912 }
15913 }
15914
Jeff Johnson295189b2012-06-20 16:38:30 -070015915 /**The get power cmd from the supplicant gets updated by the nl only
15916 *on successful execution of the function call
15917 *we are oppositely mapped w.r.t mode in the driver
15918 **/
15919 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
15920
15921 if (VOS_STATUS_E_FAILURE == vos_status)
15922 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015923 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15924 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015925 return -EINVAL;
15926 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015927 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015928 return 0;
15929}
15930
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015931static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
15932 struct net_device *dev, bool mode, int timeout)
15933{
15934 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015935
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015936 vos_ssr_protect(__func__);
15937 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
15938 vos_ssr_unprotect(__func__);
15939
15940 return ret;
15941}
Sushant Kaushik084f6592015-09-10 13:11:56 +053015942
Jeff Johnson295189b2012-06-20 16:38:30 -070015943#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015944static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
15945 struct net_device *netdev,
15946 u8 key_index)
15947{
15948 ENTER();
15949 return 0;
15950}
15951
Jeff Johnson295189b2012-06-20 16:38:30 -070015952static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015953 struct net_device *netdev,
15954 u8 key_index)
15955{
15956 int ret;
15957 vos_ssr_protect(__func__);
15958 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
15959 vos_ssr_unprotect(__func__);
15960 return ret;
15961}
15962#endif //LINUX_VERSION_CODE
15963
15964#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
15965static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
15966 struct net_device *dev,
15967 struct ieee80211_txq_params *params)
15968{
15969 ENTER();
15970 return 0;
15971}
15972#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15973static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
15974 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070015975{
Jeff Johnsone7245742012-09-05 17:12:55 -070015976 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070015977 return 0;
15978}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015979#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070015980
15981#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
15982static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015983 struct net_device *dev,
15984 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070015985{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015986 int ret;
15987
15988 vos_ssr_protect(__func__);
15989 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
15990 vos_ssr_unprotect(__func__);
15991 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015992}
15993#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15994static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
15995 struct ieee80211_txq_params *params)
15996{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015997 int ret;
15998
15999 vos_ssr_protect(__func__);
16000 ret = __wlan_hdd_set_txq_params(wiphy, params);
16001 vos_ssr_unprotect(__func__);
16002 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016003}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016004#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016005
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016006static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016007 struct net_device *dev,
16008 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070016009{
16010 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016011 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016012 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016013 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016014 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016015 v_CONTEXT_t pVosContext = NULL;
16016 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016017
Jeff Johnsone7245742012-09-05 17:12:55 -070016018 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016019
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016020 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016021 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016022 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016023 return -EINVAL;
16024 }
16025
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016026 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16027 TRACE_CODE_HDD_CFG80211_DEL_STA,
16028 pAdapter->sessionId, pAdapter->device_mode));
16029
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016030 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16031 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016032 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016033 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016034 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016035 }
16036
Jeff Johnson295189b2012-06-20 16:38:30 -070016037 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016038 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016039 )
16040 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016041 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16042 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16043 if(pSapCtx == NULL){
16044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16045 FL("psapCtx is NULL"));
16046 return -ENOENT;
16047 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016048 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016049 {
16050 v_U16_t i;
16051 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16052 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016053 if ((pSapCtx->aStaInfo[i].isUsed) &&
16054 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016055 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016056 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016057 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016058 ETHER_ADDR_LEN);
16059
Jeff Johnson295189b2012-06-20 16:38:30 -070016060 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016061 "%s: Delete STA with MAC::"
16062 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016063 __func__,
16064 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16065 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016066 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016067 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016068 }
16069 }
16070 }
16071 else
16072 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016073
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016074 vos_status = hdd_softap_GetStaId(pAdapter,
16075 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016076 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16077 {
16078 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016079 "%s: Skip this DEL STA as this is not used::"
16080 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016081 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016082 return -ENOENT;
16083 }
16084
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016085 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016086 {
16087 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016088 "%s: Skip this DEL STA as deauth is in progress::"
16089 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016090 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016091 return -ENOENT;
16092 }
16093
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016094 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016095
Jeff Johnson295189b2012-06-20 16:38:30 -070016096 hddLog(VOS_TRACE_LEVEL_INFO,
16097 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016098 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016099 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016100 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016101
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016102 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016103 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16104 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016105 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016106 hddLog(VOS_TRACE_LEVEL_INFO,
16107 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016108 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016109 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016110 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016111 return -ENOENT;
16112 }
16113
Jeff Johnson295189b2012-06-20 16:38:30 -070016114 }
16115 }
16116
16117 EXIT();
16118
16119 return 0;
16120}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016121
16122#ifdef CFG80211_DEL_STA_V2
16123static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16124 struct net_device *dev,
16125 struct station_del_parameters *param)
16126#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016127#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16128static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16129 struct net_device *dev, const u8 *mac)
16130#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016131static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16132 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016133#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016134#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016135{
16136 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016137 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016138
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016139 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016140
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016141#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016142 if (NULL == param) {
16143 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016144 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016145 return -EINVAL;
16146 }
16147
16148 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16149 param->subtype, &delStaParams);
16150
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016151#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016152 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016153 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016154#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016155 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16156
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016157 vos_ssr_unprotect(__func__);
16158
16159 return ret;
16160}
16161
16162static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016163 struct net_device *dev,
16164#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16165 const u8 *mac,
16166#else
16167 u8 *mac,
16168#endif
16169 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016170{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016171 hdd_adapter_t *pAdapter;
16172 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016173 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016174#ifdef FEATURE_WLAN_TDLS
16175 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016176
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016177 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016178
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016179 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16180 if (NULL == pAdapter)
16181 {
16182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16183 "%s: Adapter is NULL",__func__);
16184 return -EINVAL;
16185 }
16186 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16187 status = wlan_hdd_validate_context(pHddCtx);
16188 if (0 != status)
16189 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016190 return status;
16191 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016192
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016193 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16194 TRACE_CODE_HDD_CFG80211_ADD_STA,
16195 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016196 mask = params->sta_flags_mask;
16197
16198 set = params->sta_flags_set;
16199
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016201 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16202 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016203
16204 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16205 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016206 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016207 }
16208 }
16209#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016210 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016211 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016212}
16213
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016214#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16215static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16216 struct net_device *dev, const u8 *mac,
16217 struct station_parameters *params)
16218#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016219static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16220 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016221#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016222{
16223 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016224
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016225 vos_ssr_protect(__func__);
16226 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16227 vos_ssr_unprotect(__func__);
16228
16229 return ret;
16230}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016231#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016232
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016233static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016234 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016235{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016236 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16237 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016238 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016239 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016240 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016241 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016242
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016243 ENTER();
16244
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016245 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016246 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016247 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016248 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016249 return -EINVAL;
16250 }
16251
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016252 if (!pmksa) {
16253 hddLog(LOGE, FL("pmksa is NULL"));
16254 return -EINVAL;
16255 }
16256
16257 if (!pmksa->bssid || !pmksa->pmkid) {
16258 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16259 pmksa->bssid, pmksa->pmkid);
16260 return -EINVAL;
16261 }
16262
16263 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16264 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16265
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016266 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16267 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016268 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016269 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016270 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016271 }
16272
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016273 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016274 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16275
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016276 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16277 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016278
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016279 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016280 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016281 &pmk_id, 1, FALSE);
16282
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016283 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16284 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16285 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016286
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016287 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016288 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016289}
16290
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016291static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16292 struct cfg80211_pmksa *pmksa)
16293{
16294 int ret;
16295
16296 vos_ssr_protect(__func__);
16297 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16298 vos_ssr_unprotect(__func__);
16299
16300 return ret;
16301}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016302
Wilson Yang6507c4e2013-10-01 20:11:19 -070016303
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016304static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016305 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016306{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016307 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16308 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016309 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016310 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016311
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016312 ENTER();
16313
Wilson Yang6507c4e2013-10-01 20:11:19 -070016314 /* Validate pAdapter */
16315 if (NULL == pAdapter)
16316 {
16317 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16318 return -EINVAL;
16319 }
16320
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016321 if (!pmksa) {
16322 hddLog(LOGE, FL("pmksa is NULL"));
16323 return -EINVAL;
16324 }
16325
16326 if (!pmksa->bssid) {
16327 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16328 return -EINVAL;
16329 }
16330
Kiet Lam98c46a12014-10-31 15:34:57 -070016331 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16332 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16333
Wilson Yang6507c4e2013-10-01 20:11:19 -070016334 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16335 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016336 if (0 != status)
16337 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016338 return status;
16339 }
16340
16341 /*Retrieve halHandle*/
16342 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16343
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016344 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16345 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16346 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016347 /* Delete the PMKID CSR cache */
16348 if (eHAL_STATUS_SUCCESS !=
16349 sme_RoamDelPMKIDfromCache(halHandle,
16350 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16351 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16352 MAC_ADDR_ARRAY(pmksa->bssid));
16353 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016354 }
16355
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016356 EXIT();
16357 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016358}
16359
Wilson Yang6507c4e2013-10-01 20:11:19 -070016360
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016361static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16362 struct cfg80211_pmksa *pmksa)
16363{
16364 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016365
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016366 vos_ssr_protect(__func__);
16367 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16368 vos_ssr_unprotect(__func__);
16369
16370 return ret;
16371
16372}
16373
16374static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016375{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016376 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16377 tHalHandle halHandle;
16378 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016379 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016380
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016381 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016382
16383 /* Validate pAdapter */
16384 if (NULL == pAdapter)
16385 {
16386 hddLog(VOS_TRACE_LEVEL_ERROR,
16387 "%s: Invalid Adapter" ,__func__);
16388 return -EINVAL;
16389 }
16390
16391 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16392 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016393 if (0 != status)
16394 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016395 return status;
16396 }
16397
16398 /*Retrieve halHandle*/
16399 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16400
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016401 /* Flush the PMKID cache in CSR */
16402 if (eHAL_STATUS_SUCCESS !=
16403 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
16404 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
16405 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016406 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016407 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080016408 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016409}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016410
16411static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
16412{
16413 int ret;
16414
16415 vos_ssr_protect(__func__);
16416 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
16417 vos_ssr_unprotect(__func__);
16418
16419 return ret;
16420}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016421#endif
16422
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016423#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016424static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16425 struct net_device *dev,
16426 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016427{
16428 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16429 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016430 hdd_context_t *pHddCtx;
16431 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016432
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016433 ENTER();
16434
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016435 if (NULL == pAdapter)
16436 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016437 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016438 return -ENODEV;
16439 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016440 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16441 ret = wlan_hdd_validate_context(pHddCtx);
16442 if (0 != ret)
16443 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016444 return ret;
16445 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016446 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016447 if (NULL == pHddStaCtx)
16448 {
16449 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
16450 return -EINVAL;
16451 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016452
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016453 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16454 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
16455 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016456 // Added for debug on reception of Re-assoc Req.
16457 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
16458 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016459 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016460 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080016461 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016462 }
16463
16464#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080016465 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016466 ftie->ie_len);
16467#endif
16468
16469 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016470 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
16471 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016472 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016473
16474 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016475 return 0;
16476}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016477
16478static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16479 struct net_device *dev,
16480 struct cfg80211_update_ft_ies_params *ftie)
16481{
16482 int ret;
16483
16484 vos_ssr_protect(__func__);
16485 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
16486 vos_ssr_unprotect(__func__);
16487
16488 return ret;
16489}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016490#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016491
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016492#ifdef FEATURE_WLAN_SCAN_PNO
16493
16494void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
16495 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
16496{
16497 int ret;
16498 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
16499 hdd_context_t *pHddCtx;
16500
Nirav Shah80830bf2013-12-31 16:35:12 +053016501 ENTER();
16502
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016503 if (NULL == pAdapter)
16504 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016506 "%s: HDD adapter is Null", __func__);
16507 return ;
16508 }
16509
16510 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16511 if (NULL == pHddCtx)
16512 {
16513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16514 "%s: HDD context is Null!!!", __func__);
16515 return ;
16516 }
16517
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016518 spin_lock(&pHddCtx->schedScan_lock);
16519 if (TRUE == pHddCtx->isWiphySuspended)
16520 {
16521 pHddCtx->isSchedScanUpdatePending = TRUE;
16522 spin_unlock(&pHddCtx->schedScan_lock);
16523 hddLog(VOS_TRACE_LEVEL_INFO,
16524 "%s: Update cfg80211 scan database after it resume", __func__);
16525 return ;
16526 }
16527 spin_unlock(&pHddCtx->schedScan_lock);
16528
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016529 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
16530
16531 if (0 > ret)
16532 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053016533 else
16534 {
16535 /* Acquire wakelock to handle the case where APP's tries to suspend
16536 * immediatly after the driver gets connect request(i.e after pno)
16537 * from supplicant, this result in app's is suspending and not able
16538 * to process the connect request to AP */
16539 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
16540 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016541 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16543 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016544}
16545
16546/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016547 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016548 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016549 */
16550static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
16551{
16552 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16553 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016554 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016555 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16556 int status = 0;
16557 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
16558
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016559 /* The current firmware design does not allow PNO during any
16560 * active sessions. Hence, determine the active sessions
16561 * and return a failure.
16562 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016563 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
16564 {
16565 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016566 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016567
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016568 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
16569 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
16570 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
16571 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
16572 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053016573 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016574 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016575 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016576 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016577 }
16578 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16579 pAdapterNode = pNext;
16580 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016581 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016582}
16583
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016584void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
16585{
16586 hdd_adapter_t *pAdapter = callbackContext;
16587 hdd_context_t *pHddCtx;
16588
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016589 ENTER();
16590
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016591 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
16592 {
16593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16594 FL("Invalid adapter or adapter has invalid magic"));
16595 return;
16596 }
16597
16598 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16599 if (0 != wlan_hdd_validate_context(pHddCtx))
16600 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016601 return;
16602 }
16603
c_hpothub53c45d2014-08-18 16:53:14 +053016604 if (VOS_STATUS_SUCCESS != status)
16605 {
16606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016607 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053016608 pHddCtx->isPnoEnable = FALSE;
16609 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016610
16611 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
16612 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016613 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016614}
16615
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016616/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016617 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
16618 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016619 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016620static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016621 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16622{
16623 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016624 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016625 hdd_context_t *pHddCtx;
16626 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016627 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053016628 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
16629 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016630 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16631 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016632 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016633 hdd_config_t *pConfig = NULL;
16634 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016635
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016636 ENTER();
16637
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016638 if (NULL == pAdapter)
16639 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016641 "%s: HDD adapter is Null", __func__);
16642 return -ENODEV;
16643 }
16644
16645 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016646 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016647
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016648 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016649 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016650 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016651 }
16652
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016653 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016654 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16655 if (NULL == hHal)
16656 {
16657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16658 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016659 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016660 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016661 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16662 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
16663 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053016664 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016665 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053016666 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016667 {
16668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16669 "%s: aborting the existing scan is unsuccessfull", __func__);
16670 return -EBUSY;
16671 }
16672
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016673 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016674 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016676 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016677 return -EBUSY;
16678 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016679
c_hpothu37f21312014-04-09 21:49:54 +053016680 if (TRUE == pHddCtx->isPnoEnable)
16681 {
16682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16683 FL("already PNO is enabled"));
16684 return -EBUSY;
16685 }
c_hpothu225aa7c2014-10-22 17:45:13 +053016686
16687 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
16688 {
16689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16690 "%s: abort ROC failed ", __func__);
16691 return -EBUSY;
16692 }
16693
c_hpothu37f21312014-04-09 21:49:54 +053016694 pHddCtx->isPnoEnable = TRUE;
16695
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016696 pnoRequest.enable = 1; /*Enable PNO */
16697 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016698
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016699 if (( !pnoRequest.ucNetworksCount ) ||
16700 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016701 {
16702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016703 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016704 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016705 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016706 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016707 goto error;
16708 }
16709
16710 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
16711 {
16712 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016713 "%s: Incorrect number of channels %d",
16714 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016715 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016716 goto error;
16717 }
16718
16719 /* Framework provides one set of channels(all)
16720 * common for all saved profile */
16721 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16722 channels_allowed, &num_channels_allowed))
16723 {
16724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16725 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016726 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016727 goto error;
16728 }
16729 /* Checking each channel against allowed channel list */
16730 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053016731 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016732 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016733 char chList [(request->n_channels*5)+1];
16734 int len;
16735 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016736 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016737 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016738 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016739 if (request->channels[i]->hw_value == channels_allowed[indx])
16740 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016741 if ((!pConfig->enableDFSPnoChnlScan) &&
16742 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
16743 {
16744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16745 "%s : Dropping DFS channel : %d",
16746 __func__,channels_allowed[indx]);
16747 num_ignore_dfs_ch++;
16748 break;
16749 }
16750
Nirav Shah80830bf2013-12-31 16:35:12 +053016751 valid_ch[num_ch++] = request->channels[i]->hw_value;
16752 len += snprintf(chList+len, 5, "%d ",
16753 request->channels[i]->hw_value);
16754 break ;
16755 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016756 }
16757 }
Nirav Shah80830bf2013-12-31 16:35:12 +053016758 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016759
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016760 /*If all channels are DFS and dropped, then ignore the PNO request*/
16761 if (num_ignore_dfs_ch == request->n_channels)
16762 {
16763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16764 "%s : All requested channels are DFS channels", __func__);
16765 ret = -EINVAL;
16766 goto error;
16767 }
16768 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016769
16770 pnoRequest.aNetworks =
16771 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16772 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016773 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016774 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16775 FL("failed to allocate memory aNetworks %u"),
16776 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16777 goto error;
16778 }
16779 vos_mem_zero(pnoRequest.aNetworks,
16780 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16781
16782 /* Filling per profile params */
16783 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
16784 {
16785 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016786 request->match_sets[i].ssid.ssid_len;
16787
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016788 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
16789 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016790 {
16791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016792 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016793 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016794 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016795 goto error;
16796 }
16797
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016798 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016799 request->match_sets[i].ssid.ssid,
16800 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16802 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016803 i, pnoRequest.aNetworks[i].ssId.ssId);
16804 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
16805 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
16806 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016807
16808 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016809 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
16810 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016811
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016812 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016813 }
16814
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016815 for (i = 0; i < request->n_ssids; i++)
16816 {
16817 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016818 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016819 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016820 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016821 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016822 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016823 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016824 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016825 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016826 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016827 break;
16828 }
16829 j++;
16830 }
16831 }
16832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16833 "Number of hidden networks being Configured = %d",
16834 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080016836 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016837
16838 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
16839 if (pnoRequest.p24GProbeTemplate == NULL)
16840 {
16841 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16842 FL("failed to allocate memory p24GProbeTemplate %u"),
16843 SIR_PNO_MAX_PB_REQ_SIZE);
16844 goto error;
16845 }
16846
16847 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
16848 if (pnoRequest.p5GProbeTemplate == NULL)
16849 {
16850 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16851 FL("failed to allocate memory p5GProbeTemplate %u"),
16852 SIR_PNO_MAX_PB_REQ_SIZE);
16853 goto error;
16854 }
16855
16856 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
16857 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
16858
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053016859 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
16860 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016861 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016862 pnoRequest.us24GProbeTemplateLen = request->ie_len;
16863 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
16864 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016865
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016866 pnoRequest.us5GProbeTemplateLen = request->ie_len;
16867 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
16868 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016869 }
16870
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016871 /* Driver gets only one time interval which is hardcoded in
16872 * supplicant for 10000ms. Taking power consumption into account 6 timers
16873 * will be used, Timervalue is increased exponentially i.e 10,20,40,
16874 * 80,160,320 secs. And number of scan cycle for each timer
16875 * is configurable through INI param gPNOScanTimerRepeatValue.
16876 * If it is set to 0 only one timer will be used and PNO scan cycle
16877 * will be repeated after each interval specified by supplicant
16878 * till PNO is disabled.
16879 */
16880 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016881 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016882 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016883 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016884 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
16885
16886 tempInterval = (request->interval)/1000;
16887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16888 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
16889 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016890 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016891 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016892 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016893 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016894 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016895 tempInterval *= 2;
16896 }
16897 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016898 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016899
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016900 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016901
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016902 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016903 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
16904 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016905 pAdapter->pno_req_status = 0;
16906
Nirav Shah80830bf2013-12-31 16:35:12 +053016907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16908 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016909 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
16910 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053016911
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016912 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016913 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016914 hdd_cfg80211_sched_scan_done_callback, pAdapter);
16915 if (eHAL_STATUS_SUCCESS != status)
16916 {
16917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016918 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016919 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016920 goto error;
16921 }
16922
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016923 ret = wait_for_completion_timeout(
16924 &pAdapter->pno_comp_var,
16925 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
16926 if (0 >= ret)
16927 {
16928 // Did not receive the response for PNO enable in time.
16929 // Assuming the PNO enable was success.
16930 // Returning error from here, because we timeout, results
16931 // in side effect of Wifi (Wifi Setting) not to work.
16932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16933 FL("Timed out waiting for PNO to be Enabled"));
16934 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016935 }
16936
16937 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053016938 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016939
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016940error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16942 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053016943 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016944 if (pnoRequest.aNetworks)
16945 vos_mem_free(pnoRequest.aNetworks);
16946 if (pnoRequest.p24GProbeTemplate)
16947 vos_mem_free(pnoRequest.p24GProbeTemplate);
16948 if (pnoRequest.p5GProbeTemplate)
16949 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016950
16951 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016952 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016953}
16954
16955/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016956 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
16957 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016958 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016959static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
16960 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16961{
16962 int ret;
16963
16964 vos_ssr_protect(__func__);
16965 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
16966 vos_ssr_unprotect(__func__);
16967
16968 return ret;
16969}
16970
16971/*
16972 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
16973 * Function to disable PNO
16974 */
16975static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016976 struct net_device *dev)
16977{
16978 eHalStatus status = eHAL_STATUS_FAILURE;
16979 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16980 hdd_context_t *pHddCtx;
16981 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016982 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016983 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016984
16985 ENTER();
16986
16987 if (NULL == pAdapter)
16988 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016990 "%s: HDD adapter is Null", __func__);
16991 return -ENODEV;
16992 }
16993
16994 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016995
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016996 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016997 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016999 "%s: HDD context is Null", __func__);
17000 return -ENODEV;
17001 }
17002
17003 /* The return 0 is intentional when isLogpInProgress and
17004 * isLoadUnloadInProgress. We did observe a crash due to a return of
17005 * failure in sched_scan_stop , especially for a case where the unload
17006 * of the happens at the same time. The function __cfg80211_stop_sched_scan
17007 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
17008 * success. If it returns a failure , then its next invocation due to the
17009 * clean up of the second interface will have the dev pointer corresponding
17010 * to the first one leading to a crash.
17011 */
17012 if (pHddCtx->isLogpInProgress)
17013 {
17014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17015 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017016 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017017 return ret;
17018 }
17019
Mihir Shete18156292014-03-11 15:38:30 +053017020 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017021 {
17022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17023 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17024 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017025 }
17026
17027 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17028 if (NULL == hHal)
17029 {
17030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17031 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017032 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017033 }
17034
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017035 pnoRequest.enable = 0; /* Disable PNO */
17036 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017037
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017038 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17039 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17040 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017041
17042 INIT_COMPLETION(pAdapter->pno_comp_var);
17043 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17044 pnoRequest.callbackContext = pAdapter;
17045 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017046 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017047 pAdapter->sessionId,
17048 NULL, pAdapter);
17049 if (eHAL_STATUS_SUCCESS != status)
17050 {
17051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17052 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017053 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017054 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017055 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017056 ret = wait_for_completion_timeout(
17057 &pAdapter->pno_comp_var,
17058 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17059 if (0 >= ret)
17060 {
17061 // Did not receive the response for PNO disable in time.
17062 // Assuming the PNO disable was success.
17063 // Returning error from here, because we timeout, results
17064 // in side effect of Wifi (Wifi Setting) not to work.
17065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17066 FL("Timed out waiting for PNO to be disabled"));
17067 ret = 0;
17068 }
17069
17070 ret = pAdapter->pno_req_status;
17071 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017072
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017073error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017075 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017076
17077 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017078 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017079}
17080
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017081/*
17082 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17083 * NL interface to disable PNO
17084 */
17085static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17086 struct net_device *dev)
17087{
17088 int ret;
17089
17090 vos_ssr_protect(__func__);
17091 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17092 vos_ssr_unprotect(__func__);
17093
17094 return ret;
17095}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017096#endif /*FEATURE_WLAN_SCAN_PNO*/
17097
17098
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017099#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017100#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017101static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17102 struct net_device *dev,
17103 u8 *peer, u8 action_code,
17104 u8 dialog_token,
17105 u16 status_code, u32 peer_capability,
17106 const u8 *buf, size_t len)
17107#else /* TDLS_MGMT_VERSION2 */
17108#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17109static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17110 struct net_device *dev,
17111 const u8 *peer, u8 action_code,
17112 u8 dialog_token, u16 status_code,
17113 u32 peer_capability, bool initiator,
17114 const u8 *buf, size_t len)
17115#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17116static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17117 struct net_device *dev,
17118 const u8 *peer, u8 action_code,
17119 u8 dialog_token, u16 status_code,
17120 u32 peer_capability, const u8 *buf,
17121 size_t len)
17122#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17123static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17124 struct net_device *dev,
17125 u8 *peer, u8 action_code,
17126 u8 dialog_token,
17127 u16 status_code, u32 peer_capability,
17128 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017129#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017130static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17131 struct net_device *dev,
17132 u8 *peer, u8 action_code,
17133 u8 dialog_token,
17134 u16 status_code, const u8 *buf,
17135 size_t len)
17136#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017137#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017138{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017139 hdd_adapter_t *pAdapter;
17140 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017141 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017142 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017143 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017144 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017145 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017146 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017147#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017148 u32 peer_capability = 0;
17149#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017150 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017151 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017152
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017153 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17154 if (NULL == pAdapter)
17155 {
17156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17157 "%s: Adapter is NULL",__func__);
17158 return -EINVAL;
17159 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017160 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17161 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17162 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017163
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017164 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017165 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017166 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017168 "Invalid arguments");
17169 return -EINVAL;
17170 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017171
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017172 if (pHddCtx->isLogpInProgress)
17173 {
17174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17175 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017176 wlan_hdd_tdls_set_link_status(pAdapter,
17177 peer,
17178 eTDLS_LINK_IDLE,
17179 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017180 return -EBUSY;
17181 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017182
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017183 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17184 {
17185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17186 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17187 return -EAGAIN;
17188 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017189
Hoonki Lee27511902013-03-14 18:19:06 -070017190 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017191 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017193 "%s: TDLS mode is disabled OR not enabled in FW."
17194 MAC_ADDRESS_STR " action %d declined.",
17195 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017196 return -ENOTSUPP;
17197 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017198
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017199 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17200
17201 if( NULL == pHddStaCtx )
17202 {
17203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17204 "%s: HDD station context NULL ",__func__);
17205 return -EINVAL;
17206 }
17207
17208 /* STA should be connected and authenticated
17209 * before sending any TDLS frames
17210 */
17211 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17212 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17213 {
17214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17215 "STA is not connected or unauthenticated. "
17216 "connState %u, uIsAuthenticated %u",
17217 pHddStaCtx->conn_info.connState,
17218 pHddStaCtx->conn_info.uIsAuthenticated);
17219 return -EAGAIN;
17220 }
17221
Hoonki Lee27511902013-03-14 18:19:06 -070017222 /* other than teardown frame, other mgmt frames are not sent if disabled */
17223 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17224 {
17225 /* if tdls_mode is disabled to respond to peer's request */
17226 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17227 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017229 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017230 " TDLS mode is disabled. action %d declined.",
17231 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017232
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017233 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017234 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017235
17236 if (vos_max_concurrent_connections_reached())
17237 {
17238 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17239 return -EINVAL;
17240 }
Hoonki Lee27511902013-03-14 18:19:06 -070017241 }
17242
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017243 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17244 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017245 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017246 {
17247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017248 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017249 " TDLS setup is ongoing. action %d declined.",
17250 __func__, MAC_ADDR_ARRAY(peer), action_code);
17251 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017252 }
17253 }
17254
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017255 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17256 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017257 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017258 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17259 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017260 {
17261 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17262 we return error code at 'add_station()'. Hence we have this
17263 check again in addtion to add_station().
17264 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017265 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017266 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017267 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17268 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017269 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
17270 __func__, MAC_ADDR_ARRAY(peer), action_code,
17271 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053017272 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080017273 }
17274 else
17275 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017276 /* maximum reached. tweak to send error code to peer and return
17277 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017278 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17280 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017281 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
17282 __func__, MAC_ADDR_ARRAY(peer), status_code,
17283 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070017284 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017285 /* fall through to send setup resp with failure status
17286 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017287 }
17288 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017289 else
17290 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017291 mutex_lock(&pHddCtx->tdls_lock);
17292 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017293 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017294 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017295 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017296 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017297 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17298 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017299 return -EPERM;
17300 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017301 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017302 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017303 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017304
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017305 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017306 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017307 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17308 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017309
Hoonki Leea34dd892013-02-05 22:56:02 -080017310 /*Except teardown responder will not be used so just make 0*/
17311 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017312 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017313 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017314
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017315 mutex_lock(&pHddCtx->tdls_lock);
17316 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017317
17318 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17319 responder = pTdlsPeer->is_responder;
17320 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017321 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017323 "%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 -070017324 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17325 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017326 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017327 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017328 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017329 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017330 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017331
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017332 /* Discard TDLS setup if peer is removed by user app */
17333 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
17334 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17335 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
17336 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
17337
17338 mutex_lock(&pHddCtx->tdls_lock);
17339 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17340 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
17341 mutex_unlock(&pHddCtx->tdls_lock);
17342 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
17343 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
17344 MAC_ADDR_ARRAY(peer), action_code);
17345 return -EINVAL;
17346 }
17347 mutex_unlock(&pHddCtx->tdls_lock);
17348 }
17349
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017350 /* For explicit trigger of DIS_REQ come out of BMPS for
17351 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017352 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017353 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17354 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070017355 {
17356 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
17357 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017359 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017360 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
17361 if (status != VOS_STATUS_SUCCESS) {
17362 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
17363 }
Hoonki Lee14621352013-04-16 17:51:19 -070017364 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017365 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017366 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017367 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
17368 }
17369 }
Hoonki Lee14621352013-04-16 17:51:19 -070017370 }
17371
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017372 /* make sure doesn't call send_mgmt() while it is pending */
17373 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
17374 {
17375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017376 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017377 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017378 ret = -EBUSY;
17379 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017380 }
17381
17382 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017383 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
17384
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017385 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
17386 pAdapter->sessionId, peer, action_code, dialog_token,
17387 status_code, peer_capability, (tANI_U8 *)buf, len,
17388 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017389
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017390 if (VOS_STATUS_SUCCESS != status)
17391 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17393 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017394 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017395 ret = -EINVAL;
17396 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017397 }
17398
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017399 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
17400 (SIR_MAC_TDLS_DIS_RSP == action_code))
17401 {
17402 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
17403 * So we no need to wait for tdls_mgmt_comp for sending ack status.
17404 */
17405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17406 "%s: tx done for frm %u", __func__, action_code);
17407 return 0;
17408 }
17409
17410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17411 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
17412 WAIT_TIME_TDLS_MGMT);
17413
Hoonki Leed37cbb32013-04-20 00:31:14 -070017414 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
17415 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
17416
17417 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017418 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070017419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070017420 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070017421 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017422 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080017423
17424 if (pHddCtx->isLogpInProgress)
17425 {
17426 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17427 "%s: LOGP in Progress. Ignore!!!", __func__);
17428 return -EAGAIN;
17429 }
Abhishek Singh837adf22015-10-01 17:37:37 +053017430 if (rc <= 0)
17431 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
17432 WLAN_LOG_INDICATOR_HOST_DRIVER,
17433 WLAN_LOG_REASON_HDD_TIME_OUT,
17434 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080017435
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017436 ret = -EINVAL;
17437 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017438 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017439 else
17440 {
17441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17442 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
17443 __func__, rc, pAdapter->mgmtTxCompletionStatus);
17444 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017445
Gopichand Nakkala05922802013-03-14 12:23:19 -070017446 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070017447 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017448 ret = max_sta_failed;
17449 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070017450 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017451
Hoonki Leea34dd892013-02-05 22:56:02 -080017452 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
17453 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017454 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17456 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017457 }
17458 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
17459 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017460 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017461 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17462 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017463 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017464
17465 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017466
17467tx_failed:
17468 /* add_station will be called before sending TDLS_SETUP_REQ and
17469 * TDLS_SETUP_RSP and as part of add_station driver will enable
17470 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
17471 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
17472 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
17473 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
17474 */
17475
17476 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17477 (SIR_MAC_TDLS_SETUP_RSP == action_code))
17478 wlan_hdd_tdls_check_bmps(pAdapter);
17479 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017480}
17481
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017482#if TDLS_MGMT_VERSION2
17483static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17484 u8 *peer, u8 action_code, u8 dialog_token,
17485 u16 status_code, u32 peer_capability,
17486 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017487#else /* TDLS_MGMT_VERSION2 */
17488#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17489static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17490 struct net_device *dev,
17491 const u8 *peer, u8 action_code,
17492 u8 dialog_token, u16 status_code,
17493 u32 peer_capability, bool initiator,
17494 const u8 *buf, size_t len)
17495#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17496static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17497 struct net_device *dev,
17498 const u8 *peer, u8 action_code,
17499 u8 dialog_token, u16 status_code,
17500 u32 peer_capability, const u8 *buf,
17501 size_t len)
17502#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17503static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17504 struct net_device *dev,
17505 u8 *peer, u8 action_code,
17506 u8 dialog_token,
17507 u16 status_code, u32 peer_capability,
17508 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017509#else
17510static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17511 u8 *peer, u8 action_code, u8 dialog_token,
17512 u16 status_code, const u8 *buf, size_t len)
17513#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017514#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017515{
17516 int ret;
17517
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017518 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017519#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017520 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17521 dialog_token, status_code,
17522 peer_capability, buf, len);
17523#else /* TDLS_MGMT_VERSION2 */
17524#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17525 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17526 dialog_token, status_code,
17527 peer_capability, initiator,
17528 buf, len);
17529#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17530 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17531 dialog_token, status_code,
17532 peer_capability, buf, len);
17533#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17534 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17535 dialog_token, status_code,
17536 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017537#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017538 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17539 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017540#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017541#endif
17542 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017543
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017544 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017545}
Atul Mittal115287b2014-07-08 13:26:33 +053017546
17547int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017548#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17549 const u8 *peer,
17550#else
Atul Mittal115287b2014-07-08 13:26:33 +053017551 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017552#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017553 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053017554 cfg80211_exttdls_callback callback)
17555{
17556
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017557 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053017558 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017559 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053017560 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17561 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
17562 __func__, MAC_ADDR_ARRAY(peer));
17563
17564 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17565 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17566
17567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017568 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17569 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17570 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017571 return -ENOTSUPP;
17572 }
17573
17574 /* To cater the requirement of establishing the TDLS link
17575 * irrespective of the data traffic , get an entry of TDLS peer.
17576 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017577 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017578 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
17579 if (pTdlsPeer == NULL) {
17580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17581 "%s: peer " MAC_ADDRESS_STR " not existing",
17582 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017583 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017584 return -EINVAL;
17585 }
17586
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017587 /* check FW TDLS Off Channel capability */
17588 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017589 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017590 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017591 {
17592 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
17593 pTdlsPeer->peerParams.global_operating_class =
17594 tdls_peer_params->global_operating_class;
17595 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
17596 pTdlsPeer->peerParams.min_bandwidth_kbps =
17597 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017598 /* check configured channel is valid, non dfs and
17599 * not current operating channel */
17600 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
17601 tdls_peer_params->channel)) &&
17602 (pHddStaCtx) &&
17603 (tdls_peer_params->channel !=
17604 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017605 {
17606 pTdlsPeer->isOffChannelConfigured = TRUE;
17607 }
17608 else
17609 {
17610 pTdlsPeer->isOffChannelConfigured = FALSE;
17611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17612 "%s: Configured Tdls Off Channel is not valid", __func__);
17613
17614 }
17615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017616 "%s: tdls_off_channel %d isOffChannelConfigured %d "
17617 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017618 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017619 pTdlsPeer->isOffChannelConfigured,
17620 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017621 }
17622 else
17623 {
17624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017625 "%s: TDLS off channel FW capability %d, "
17626 "host capab %d or Invalid TDLS Peer Params", __func__,
17627 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
17628 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017629 }
17630
Atul Mittal115287b2014-07-08 13:26:33 +053017631 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
17632
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017633 mutex_unlock(&pHddCtx->tdls_lock);
17634
Atul Mittal115287b2014-07-08 13:26:33 +053017635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17636 " %s TDLS Add Force Peer Failed",
17637 __func__);
17638 return -EINVAL;
17639 }
17640 /*EXT TDLS*/
17641
17642 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017643 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17645 " %s TDLS set callback Failed",
17646 __func__);
17647 return -EINVAL;
17648 }
17649
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017650 mutex_unlock(&pHddCtx->tdls_lock);
17651
Atul Mittal115287b2014-07-08 13:26:33 +053017652 return(0);
17653
17654}
17655
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017656int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
17657#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17658 const u8 *peer
17659#else
17660 u8 *peer
17661#endif
17662)
Atul Mittal115287b2014-07-08 13:26:33 +053017663{
17664
17665 hddTdlsPeer_t *pTdlsPeer;
17666 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17668 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
17669 __func__, MAC_ADDR_ARRAY(peer));
17670
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017671 if (0 != wlan_hdd_validate_context(pHddCtx)) {
17672 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
17673 return -EINVAL;
17674 }
17675
Atul Mittal115287b2014-07-08 13:26:33 +053017676 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17677 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17678
17679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017680 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17681 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17682 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017683 return -ENOTSUPP;
17684 }
17685
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017686 mutex_lock(&pHddCtx->tdls_lock);
17687 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053017688
17689 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017690 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017691 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017692 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053017693 __func__, MAC_ADDR_ARRAY(peer));
17694 return -EINVAL;
17695 }
17696 else {
17697 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
17698 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017699 /* if channel switch is configured, reset
17700 the channel for this peer */
17701 if (TRUE == pTdlsPeer->isOffChannelConfigured)
17702 {
17703 pTdlsPeer->peerParams.channel = 0;
17704 pTdlsPeer->isOffChannelConfigured = FALSE;
17705 }
Atul Mittal115287b2014-07-08 13:26:33 +053017706 }
17707
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017708 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017709 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017710 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053017711 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017712 }
Atul Mittal115287b2014-07-08 13:26:33 +053017713
17714 /*EXT TDLS*/
17715
17716 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017717 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17719 " %s TDLS set callback Failed",
17720 __func__);
17721 return -EINVAL;
17722 }
Atul Mittal115287b2014-07-08 13:26:33 +053017723
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017724 mutex_unlock(&pHddCtx->tdls_lock);
17725
17726 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053017727}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017728static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17730 const u8 *peer,
17731#else
17732 u8 *peer,
17733#endif
17734 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017735{
17736 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17737 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017738 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017739 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017740
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017741 ENTER();
17742
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017743 if (!pAdapter) {
17744 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17745 return -EINVAL;
17746 }
17747
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017748 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17749 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
17750 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017751 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017752 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070017754 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017755 return -EINVAL;
17756 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017757
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017758 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017759 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017760 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017761 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017762 }
17763
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017764
17765 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017766 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017767 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017769 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
17770 "Cannot process TDLS commands",
17771 pHddCtx->cfg_ini->fEnableTDLSSupport,
17772 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017773 return -ENOTSUPP;
17774 }
17775
17776 switch (oper) {
17777 case NL80211_TDLS_ENABLE_LINK:
17778 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017779 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017780 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017781 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053017782 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017783 tANI_U16 numCurrTdlsPeers = 0;
17784 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017785 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017786
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017787 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17788 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
17789 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017790
Sunil Dutt41de4e22013-11-14 18:09:02 +053017791 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053017792 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053017793 if ( NULL == pTdlsPeer ) {
17794 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
17795 " (oper %d) not exsting. ignored",
17796 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
17797 return -EINVAL;
17798 }
17799
17800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17801 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
17802 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
17803 "NL80211_TDLS_ENABLE_LINK");
17804
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070017805 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
17806 {
17807 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
17808 MAC_ADDRESS_STR " failed",
17809 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
17810 return -EINVAL;
17811 }
17812
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053017813 /* before starting tdls connection, set tdls
17814 * off channel established status to default value */
17815 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017816 /* TDLS Off Channel, Disable tdls channel switch,
17817 when there are more than one tdls link */
17818 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053017819 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017820 {
17821 /* get connected peer and send disable tdls off chan */
17822 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017823 if ((connPeer) &&
17824 (connPeer->isOffChannelSupported == TRUE) &&
17825 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017826 {
17827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17828 "%s: More then one peer connected, Disable "
17829 "TDLS channel switch", __func__);
17830
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017831 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017832
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017833 ret = sme_SendTdlsChanSwitchReq(
17834 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017835 pAdapter->sessionId,
17836 connPeer->peerMac,
17837 connPeer->peerParams.channel,
17838 TDLS_OFF_CHANNEL_BW_OFFSET,
17839 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017840 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017841 hddLog(VOS_TRACE_LEVEL_ERROR,
17842 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017843 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017844 }
17845 else
17846 {
17847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17848 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017849 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017850 "isOffChannelConfigured %d",
17851 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017852 (connPeer ? (connPeer->isOffChannelSupported)
17853 : -1),
17854 (connPeer ? (connPeer->isOffChannelConfigured)
17855 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017856 }
17857 }
17858
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017859 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017860 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017861 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053017862
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017863 if (0 != wlan_hdd_tdls_get_link_establish_params(
17864 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017865 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017866 return -EINVAL;
17867 }
17868 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017869
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017870 ret = sme_SendTdlsLinkEstablishParams(
17871 WLAN_HDD_GET_HAL_CTX(pAdapter),
17872 pAdapter->sessionId, peer,
17873 &tdlsLinkEstablishParams);
17874 if (ret != VOS_STATUS_SUCCESS) {
17875 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
17876 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017877 /* Send TDLS peer UAPSD capabilities to the firmware and
17878 * register with the TL on after the response for this operation
17879 * is received .
17880 */
17881 ret = wait_for_completion_interruptible_timeout(
17882 &pAdapter->tdls_link_establish_req_comp,
17883 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
17884 if (ret <= 0)
17885 {
17886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017887 FL("Link Establish Request Failed Status %ld"),
17888 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017889 return -EINVAL;
17890 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017891 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017892
Atul Mittal115287b2014-07-08 13:26:33 +053017893 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
17894 eTDLS_LINK_CONNECTED,
17895 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053017896 staDesc.ucSTAId = pTdlsPeer->staId;
17897 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017898 ret = WLANTL_UpdateTdlsSTAClient(
17899 pHddCtx->pvosContext,
17900 &staDesc);
17901 if (ret != VOS_STATUS_SUCCESS) {
17902 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
17903 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053017904
Gopichand Nakkala471708b2013-06-04 20:03:01 +053017905 /* Mark TDLS client Authenticated .*/
17906 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
17907 pTdlsPeer->staId,
17908 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070017909 if (VOS_STATUS_SUCCESS == status)
17910 {
Hoonki Lee14621352013-04-16 17:51:19 -070017911 if (pTdlsPeer->is_responder == 0)
17912 {
17913 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053017914 tdlsConnInfo_t *tdlsInfo;
17915
17916 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
17917
17918 /* Initialize initiator wait callback */
17919 vos_timer_init(
17920 &pTdlsPeer->initiatorWaitTimeoutTimer,
17921 VOS_TIMER_TYPE_SW,
17922 wlan_hdd_tdls_initiator_wait_cb,
17923 tdlsInfo);
Hoonki Lee14621352013-04-16 17:51:19 -070017924
17925 wlan_hdd_tdls_timer_restart(pAdapter,
17926 &pTdlsPeer->initiatorWaitTimeoutTimer,
17927 WAIT_TIME_TDLS_INITIATOR);
17928 /* suspend initiator TX until it receives direct packet from the
17929 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017930 ret = WLANTL_SuspendDataTx(
17931 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
17932 &staId, NULL);
17933 if (ret != VOS_STATUS_SUCCESS) {
17934 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
17935 }
Hoonki Lee14621352013-04-16 17:51:19 -070017936 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017937
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017938 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017939 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017940 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017941 suppChannelLen =
17942 tdlsLinkEstablishParams.supportedChannelsLen;
17943
17944 if ((suppChannelLen > 0) &&
17945 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
17946 {
17947 tANI_U8 suppPeerChannel = 0;
17948 int i = 0;
17949 for (i = 0U; i < suppChannelLen; i++)
17950 {
17951 suppPeerChannel =
17952 tdlsLinkEstablishParams.supportedChannels[i];
17953
17954 pTdlsPeer->isOffChannelSupported = FALSE;
17955 if (suppPeerChannel ==
17956 pTdlsPeer->peerParams.channel)
17957 {
17958 pTdlsPeer->isOffChannelSupported = TRUE;
17959 break;
17960 }
17961 }
17962 }
17963 else
17964 {
17965 pTdlsPeer->isOffChannelSupported = FALSE;
17966 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017967 }
17968 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17969 "%s: TDLS channel switch request for channel "
17970 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017971 "%d isOffChannelSupported %d", __func__,
17972 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017973 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017974 suppChannelLen,
17975 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017976
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017977 /* TDLS Off Channel, Enable tdls channel switch,
17978 when their is only one tdls link and it supports */
17979 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17980 if ((numCurrTdlsPeers == 1) &&
17981 (TRUE == pTdlsPeer->isOffChannelSupported) &&
17982 (TRUE == pTdlsPeer->isOffChannelConfigured))
17983 {
17984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17985 "%s: Send TDLS channel switch request for channel %d",
17986 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017987
17988 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017989 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
17990 pAdapter->sessionId,
17991 pTdlsPeer->peerMac,
17992 pTdlsPeer->peerParams.channel,
17993 TDLS_OFF_CHANNEL_BW_OFFSET,
17994 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017995 if (ret != VOS_STATUS_SUCCESS) {
17996 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
17997 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017998 }
17999 else
18000 {
18001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18002 "%s: TDLS channel switch request not sent"
18003 " numCurrTdlsPeers %d "
18004 "isOffChannelSupported %d "
18005 "isOffChannelConfigured %d",
18006 __func__, numCurrTdlsPeers,
18007 pTdlsPeer->isOffChannelSupported,
18008 pTdlsPeer->isOffChannelConfigured);
18009 }
18010
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018011 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018012 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018013
18014 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018015 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18016 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018017 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018018 int ac;
18019 uint8 ucAc[4] = { WLANTL_AC_VO,
18020 WLANTL_AC_VI,
18021 WLANTL_AC_BK,
18022 WLANTL_AC_BE };
18023 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18024 for(ac=0; ac < 4; ac++)
18025 {
18026 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18027 pTdlsPeer->staId, ucAc[ac],
18028 tlTid[ac], tlTid[ac], 0, 0,
18029 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018030 if (status != VOS_STATUS_SUCCESS) {
18031 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18032 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018033 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018034 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018035 }
Bhargav Shah66896792015-10-01 18:17:37 +053018036 /* stop TCP delack timer if TDLS is enable */
18037 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18038 hdd_manage_delack_timer(pHddCtx);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018039 }
18040 break;
18041 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018042 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018043 tANI_U16 numCurrTdlsPeers = 0;
18044 hddTdlsPeer_t *connPeer = NULL;
18045
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18047 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18048 __func__, MAC_ADDR_ARRAY(peer));
18049
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018050 mutex_lock(&pHddCtx->tdls_lock);
18051 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018052
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018053
Sunil Dutt41de4e22013-11-14 18:09:02 +053018054 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018055 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018056 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18057 " (oper %d) not exsting. ignored",
18058 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18059 return -EINVAL;
18060 }
18061
18062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18063 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18064 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18065 "NL80211_TDLS_DISABLE_LINK");
18066
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018067 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018068 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018069 long status;
18070
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018071 /* set tdls off channel status to false for this peer */
18072 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018073 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18074 eTDLS_LINK_TEARING,
18075 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18076 eTDLS_LINK_UNSPECIFIED:
18077 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018078 mutex_unlock(&pHddCtx->tdls_lock);
18079
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018080 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18081
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018082 status = sme_DeleteTdlsPeerSta(
18083 WLAN_HDD_GET_HAL_CTX(pAdapter),
18084 pAdapter->sessionId, peer );
18085 if (status != VOS_STATUS_SUCCESS) {
18086 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18087 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018088
18089 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18090 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018091
18092 mutex_lock(&pHddCtx->tdls_lock);
18093 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18094 if ( NULL == pTdlsPeer ) {
18095 mutex_unlock(&pHddCtx->tdls_lock);
18096 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18097 " peer was freed in other context",
18098 __func__, MAC_ADDR_ARRAY(peer));
18099 return -EINVAL;
18100 }
18101
Atul Mittal271a7652014-09-12 13:18:22 +053018102 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053018103 eTDLS_LINK_IDLE,
18104 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018105 mutex_unlock(&pHddCtx->tdls_lock);
18106
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018107 if (status <= 0)
18108 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18110 "%s: Del station failed status %ld",
18111 __func__, status);
18112 return -EPERM;
18113 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018114
18115 /* TDLS Off Channel, Enable tdls channel switch,
18116 when their is only one tdls link and it supports */
18117 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18118 if (numCurrTdlsPeers == 1)
18119 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018120 tSirMacAddr peerMac;
18121 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018122
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018123 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018124 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018125
18126 if (connPeer == NULL) {
18127 mutex_unlock(&pHddCtx->tdls_lock);
18128 hddLog(VOS_TRACE_LEVEL_ERROR,
18129 "%s connPeer is NULL", __func__);
18130 return -EINVAL;
18131 }
18132
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018133 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18134 channel = connPeer->peerParams.channel;
18135
18136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18137 "%s: TDLS channel switch "
18138 "isOffChannelSupported %d "
18139 "isOffChannelConfigured %d "
18140 "isOffChannelEstablished %d",
18141 __func__,
18142 (connPeer ? connPeer->isOffChannelSupported : -1),
18143 (connPeer ? connPeer->isOffChannelConfigured : -1),
18144 (connPeer ? connPeer->isOffChannelEstablished : -1));
18145
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018146 if ((connPeer) &&
18147 (connPeer->isOffChannelSupported == TRUE) &&
18148 (connPeer->isOffChannelConfigured == TRUE))
18149 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018150 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018151 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018152 status = sme_SendTdlsChanSwitchReq(
18153 WLAN_HDD_GET_HAL_CTX(pAdapter),
18154 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018155 peerMac,
18156 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018157 TDLS_OFF_CHANNEL_BW_OFFSET,
18158 TDLS_CHANNEL_SWITCH_ENABLE);
18159 if (status != VOS_STATUS_SUCCESS) {
18160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18161 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018162 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018163 else
18164 mutex_unlock(&pHddCtx->tdls_lock);
18165 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018166 else
18167 {
18168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18169 "%s: TDLS channel switch request not sent "
18170 "numCurrTdlsPeers %d ",
18171 __func__, numCurrTdlsPeers);
18172 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018173 }
18174 else
18175 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018176 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18178 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080018179 }
Bhargav Shah66896792015-10-01 18:17:37 +053018180 if (numCurrTdlsPeers == 0) {
18181 /* start TCP delack timer if TDLS is disable */
18182 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18183 hdd_manage_delack_timer(pHddCtx);
18184 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018185 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018186 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018187 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018188 {
Atul Mittal115287b2014-07-08 13:26:33 +053018189 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018190
Atul Mittal115287b2014-07-08 13:26:33 +053018191 if (0 != status)
18192 {
18193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018194 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053018195 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018196 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053018197 break;
18198 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018199 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018200 {
Atul Mittal115287b2014-07-08 13:26:33 +053018201 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
18202 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018203 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053018204 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018205
Atul Mittal115287b2014-07-08 13:26:33 +053018206 if (0 != status)
18207 {
18208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018209 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053018210 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053018211 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053018212 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018213 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018214 case NL80211_TDLS_DISCOVERY_REQ:
18215 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018217 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018218 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018219 return -ENOTSUPP;
18220 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18222 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018223 return -ENOTSUPP;
18224 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018225
18226 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018227 return 0;
18228}
Chilam NG571c65a2013-01-19 12:27:36 +053018229
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018230static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018231#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18232 const u8 *peer,
18233#else
18234 u8 *peer,
18235#endif
18236 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018237{
18238 int ret;
18239
18240 vos_ssr_protect(__func__);
18241 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
18242 vos_ssr_unprotect(__func__);
18243
18244 return ret;
18245}
18246
Chilam NG571c65a2013-01-19 12:27:36 +053018247int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
18248 struct net_device *dev, u8 *peer)
18249{
Arif Hussaina7c8e412013-11-20 11:06:42 -080018250 hddLog(VOS_TRACE_LEVEL_INFO,
18251 "tdls send discover req: "MAC_ADDRESS_STR,
18252 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053018253
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018254#if TDLS_MGMT_VERSION2
18255 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18256 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18257#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018258#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18259 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18260 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
18261#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18262 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18263 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18264#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18265 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18266 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18267#else
Chilam NG571c65a2013-01-19 12:27:36 +053018268 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18269 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018270#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018271#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053018272}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018273#endif
18274
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018275#ifdef WLAN_FEATURE_GTK_OFFLOAD
18276/*
18277 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
18278 * Callback rountine called upon receiving response for
18279 * get offload info
18280 */
18281void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
18282 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
18283{
18284
18285 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018286 tANI_U8 tempReplayCounter[8];
18287 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018288
18289 ENTER();
18290
18291 if (NULL == pAdapter)
18292 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018294 "%s: HDD adapter is Null", __func__);
18295 return ;
18296 }
18297
18298 if (NULL == pGtkOffloadGetInfoRsp)
18299 {
18300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18301 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
18302 return ;
18303 }
18304
18305 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
18306 {
18307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18308 "%s: wlan Failed to get replay counter value",
18309 __func__);
18310 return ;
18311 }
18312
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018313 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18314 /* Update replay counter */
18315 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
18316 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18317
18318 {
18319 /* changing from little to big endian since supplicant
18320 * works on big endian format
18321 */
18322 int i;
18323 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18324
18325 for (i = 0; i < 8; i++)
18326 {
18327 tempReplayCounter[7-i] = (tANI_U8)p[i];
18328 }
18329 }
18330
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018331 /* Update replay counter to NL */
18332 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018333 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018334}
18335
18336/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018337 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018338 * This function is used to offload GTK rekeying job to the firmware.
18339 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018340int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018341 struct cfg80211_gtk_rekey_data *data)
18342{
18343 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18344 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18345 hdd_station_ctx_t *pHddStaCtx;
18346 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018347 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018348 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018349 eHalStatus status = eHAL_STATUS_FAILURE;
18350
18351 ENTER();
18352
18353 if (NULL == pAdapter)
18354 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018355 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018356 "%s: HDD adapter is Null", __func__);
18357 return -ENODEV;
18358 }
18359
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018360 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18361 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
18362 pAdapter->sessionId, pAdapter->device_mode));
18363
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018364 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018365 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018366 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018367 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018368 }
18369
18370 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18371 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18372 if (NULL == hHal)
18373 {
18374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18375 "%s: HAL context is Null!!!", __func__);
18376 return -EAGAIN;
18377 }
18378
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018379 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
18380 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
18381 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
18382 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018383 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018384 {
18385 /* changing from big to little endian since driver
18386 * works on little endian format
18387 */
18388 tANI_U8 *p =
18389 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
18390 int i;
18391
18392 for (i = 0; i < 8; i++)
18393 {
18394 p[7-i] = data->replay_ctr[i];
18395 }
18396 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018397
18398 if (TRUE == pHddCtx->hdd_wlan_suspended)
18399 {
18400 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018401 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
18402 sizeof (tSirGtkOffloadParams));
18403 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018404 pAdapter->sessionId);
18405
18406 if (eHAL_STATUS_SUCCESS != status)
18407 {
18408 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18409 "%s: sme_SetGTKOffload failed, returned %d",
18410 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018411
18412 /* Need to clear any trace of key value in the memory.
18413 * Thus zero out the memory even though it is local
18414 * variable.
18415 */
18416 vos_mem_zero(&hddGtkOffloadReqParams,
18417 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018418 return status;
18419 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018420 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18421 "%s: sme_SetGTKOffload successfull", __func__);
18422 }
18423 else
18424 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18426 "%s: wlan not suspended GTKOffload request is stored",
18427 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018428 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018429
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018430 /* Need to clear any trace of key value in the memory.
18431 * Thus zero out the memory even though it is local
18432 * variable.
18433 */
18434 vos_mem_zero(&hddGtkOffloadReqParams,
18435 sizeof(hddGtkOffloadReqParams));
18436
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018437 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018438 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018439}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018440
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018441int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
18442 struct cfg80211_gtk_rekey_data *data)
18443{
18444 int ret;
18445
18446 vos_ssr_protect(__func__);
18447 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
18448 vos_ssr_unprotect(__func__);
18449
18450 return ret;
18451}
18452#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018453/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018454 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018455 * This function is used to set access control policy
18456 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018457static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18458 struct net_device *dev,
18459 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018460{
18461 int i;
18462 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18463 hdd_hostapd_state_t *pHostapdState;
18464 tsap_Config_t *pConfig;
18465 v_CONTEXT_t pVosContext = NULL;
18466 hdd_context_t *pHddCtx;
18467 int status;
18468
18469 ENTER();
18470
18471 if (NULL == pAdapter)
18472 {
18473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18474 "%s: HDD adapter is Null", __func__);
18475 return -ENODEV;
18476 }
18477
18478 if (NULL == params)
18479 {
18480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18481 "%s: params is Null", __func__);
18482 return -EINVAL;
18483 }
18484
18485 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18486 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018487 if (0 != status)
18488 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018489 return status;
18490 }
18491
18492 pVosContext = pHddCtx->pvosContext;
18493 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
18494
18495 if (NULL == pHostapdState)
18496 {
18497 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18498 "%s: pHostapdState is Null", __func__);
18499 return -EINVAL;
18500 }
18501
18502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
18503 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018504 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18505 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
18506 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018507
18508 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
18509 {
18510 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
18511
18512 /* default value */
18513 pConfig->num_accept_mac = 0;
18514 pConfig->num_deny_mac = 0;
18515
18516 /**
18517 * access control policy
18518 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
18519 * listed in hostapd.deny file.
18520 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
18521 * listed in hostapd.accept file.
18522 */
18523 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
18524 {
18525 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
18526 }
18527 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
18528 {
18529 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
18530 }
18531 else
18532 {
18533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18534 "%s:Acl Policy : %d is not supported",
18535 __func__, params->acl_policy);
18536 return -ENOTSUPP;
18537 }
18538
18539 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
18540 {
18541 pConfig->num_accept_mac = params->n_acl_entries;
18542 for (i = 0; i < params->n_acl_entries; i++)
18543 {
18544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18545 "** Add ACL MAC entry %i in WhiletList :"
18546 MAC_ADDRESS_STR, i,
18547 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18548
18549 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
18550 sizeof(qcmacaddr));
18551 }
18552 }
18553 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
18554 {
18555 pConfig->num_deny_mac = params->n_acl_entries;
18556 for (i = 0; i < params->n_acl_entries; i++)
18557 {
18558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18559 "** Add ACL MAC entry %i in BlackList :"
18560 MAC_ADDRESS_STR, i,
18561 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18562
18563 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
18564 sizeof(qcmacaddr));
18565 }
18566 }
18567
18568 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
18569 {
18570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18571 "%s: SAP Set Mac Acl fail", __func__);
18572 return -EINVAL;
18573 }
18574 }
18575 else
18576 {
18577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053018578 "%s: Invalid device_mode = %s (%d)",
18579 __func__, hdd_device_modetoString(pAdapter->device_mode),
18580 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018581 return -EINVAL;
18582 }
18583
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018584 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018585 return 0;
18586}
18587
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018588static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18589 struct net_device *dev,
18590 const struct cfg80211_acl_data *params)
18591{
18592 int ret;
18593 vos_ssr_protect(__func__);
18594 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
18595 vos_ssr_unprotect(__func__);
18596
18597 return ret;
18598}
18599
Leo Chang9056f462013-08-01 19:21:11 -070018600#ifdef WLAN_NL80211_TESTMODE
18601#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070018602void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070018603(
18604 void *pAdapter,
18605 void *indCont
18606)
18607{
Leo Changd9df8aa2013-09-26 13:32:26 -070018608 tSirLPHBInd *lphbInd;
18609 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053018610 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070018611
18612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018613 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070018614
c_hpothu73f35e62014-04-18 13:40:08 +053018615 if (pAdapter == NULL)
18616 {
18617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18618 "%s: pAdapter is NULL\n",__func__);
18619 return;
18620 }
18621
Leo Chang9056f462013-08-01 19:21:11 -070018622 if (NULL == indCont)
18623 {
18624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018625 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070018626 return;
18627 }
18628
c_hpothu73f35e62014-04-18 13:40:08 +053018629 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070018630 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070018631 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053018632 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070018633 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070018634 GFP_ATOMIC);
18635 if (!skb)
18636 {
18637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18638 "LPHB timeout, NL buffer alloc fail");
18639 return;
18640 }
18641
Leo Changac3ba772013-10-07 09:47:04 -070018642 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070018643 {
18644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18645 "WLAN_HDD_TM_ATTR_CMD put fail");
18646 goto nla_put_failure;
18647 }
Leo Changac3ba772013-10-07 09:47:04 -070018648 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070018649 {
18650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18651 "WLAN_HDD_TM_ATTR_TYPE put fail");
18652 goto nla_put_failure;
18653 }
Leo Changac3ba772013-10-07 09:47:04 -070018654 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070018655 sizeof(tSirLPHBInd), lphbInd))
18656 {
18657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18658 "WLAN_HDD_TM_ATTR_DATA put fail");
18659 goto nla_put_failure;
18660 }
Leo Chang9056f462013-08-01 19:21:11 -070018661 cfg80211_testmode_event(skb, GFP_ATOMIC);
18662 return;
18663
18664nla_put_failure:
18665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18666 "NLA Put fail");
18667 kfree_skb(skb);
18668
18669 return;
18670}
18671#endif /* FEATURE_WLAN_LPHB */
18672
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018673static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070018674{
18675 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
18676 int err = 0;
18677#ifdef FEATURE_WLAN_LPHB
18678 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070018679 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018680
18681 ENTER();
18682
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018683 err = wlan_hdd_validate_context(pHddCtx);
18684 if (0 != err)
18685 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018686 return err;
18687 }
Leo Chang9056f462013-08-01 19:21:11 -070018688#endif /* FEATURE_WLAN_LPHB */
18689
18690 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
18691 if (err)
18692 {
18693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18694 "%s Testmode INV ATTR", __func__);
18695 return err;
18696 }
18697
18698 if (!tb[WLAN_HDD_TM_ATTR_CMD])
18699 {
18700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18701 "%s Testmode INV CMD", __func__);
18702 return -EINVAL;
18703 }
18704
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018705 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18706 TRACE_CODE_HDD_CFG80211_TESTMODE,
18707 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070018708 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
18709 {
18710#ifdef FEATURE_WLAN_LPHB
18711 /* Low Power Heartbeat configuration request */
18712 case WLAN_HDD_TM_CMD_WLAN_HB:
18713 {
18714 int buf_len;
18715 void *buf;
18716 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080018717 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070018718
18719 if (!tb[WLAN_HDD_TM_ATTR_DATA])
18720 {
18721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18722 "%s Testmode INV DATA", __func__);
18723 return -EINVAL;
18724 }
18725
18726 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
18727 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080018728
18729 hb_params_temp =(tSirLPHBReq *)buf;
18730 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
18731 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
18732 return -EINVAL;
18733
Leo Chang9056f462013-08-01 19:21:11 -070018734 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
18735 if (NULL == hb_params)
18736 {
18737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18738 "%s Request Buffer Alloc Fail", __func__);
18739 return -EINVAL;
18740 }
18741
18742 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070018743 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
18744 hb_params,
18745 wlan_hdd_cfg80211_lphb_ind_handler);
18746 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070018747 {
Leo Changd9df8aa2013-09-26 13:32:26 -070018748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18749 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070018750 vos_mem_free(hb_params);
18751 }
Leo Chang9056f462013-08-01 19:21:11 -070018752 return 0;
18753 }
18754#endif /* FEATURE_WLAN_LPHB */
18755 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018756 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18757 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070018758 return -EOPNOTSUPP;
18759 }
18760
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018761 EXIT();
18762 return err;
Leo Chang9056f462013-08-01 19:21:11 -070018763}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018764
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053018765static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
18766#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
18767 struct wireless_dev *wdev,
18768#endif
18769 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018770{
18771 int ret;
18772
18773 vos_ssr_protect(__func__);
18774 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
18775 vos_ssr_unprotect(__func__);
18776
18777 return ret;
18778}
Leo Chang9056f462013-08-01 19:21:11 -070018779#endif /* CONFIG_NL80211_TESTMODE */
18780
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018781static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018782 struct net_device *dev,
18783 int idx, struct survey_info *survey)
18784{
18785 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18786 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053018787 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018788 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053018789 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018790 v_S7_t snr,rssi;
18791 int status, i, j, filled = 0;
18792
18793 ENTER();
18794
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018795 if (NULL == pAdapter)
18796 {
18797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18798 "%s: HDD adapter is Null", __func__);
18799 return -ENODEV;
18800 }
18801
18802 if (NULL == wiphy)
18803 {
18804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18805 "%s: wiphy is Null", __func__);
18806 return -ENODEV;
18807 }
18808
18809 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18810 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018811 if (0 != status)
18812 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018813 return status;
18814 }
18815
Mihir Sheted9072e02013-08-21 17:02:29 +053018816 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18817
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018818 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053018819 0 != pAdapter->survey_idx ||
18820 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018821 {
18822 /* The survey dump ops when implemented completely is expected to
18823 * return a survey of all channels and the ops is called by the
18824 * kernel with incremental values of the argument 'idx' till it
18825 * returns -ENONET. But we can only support the survey for the
18826 * operating channel for now. survey_idx is used to track
18827 * that the ops is called only once and then return -ENONET for
18828 * the next iteration
18829 */
18830 pAdapter->survey_idx = 0;
18831 return -ENONET;
18832 }
18833
Mukul Sharma9d5233b2015-06-11 20:28:20 +053018834 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18835 {
18836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18837 "%s: Roaming in progress, hence return ", __func__);
18838 return -ENONET;
18839 }
18840
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018841 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18842
18843 wlan_hdd_get_snr(pAdapter, &snr);
18844 wlan_hdd_get_rssi(pAdapter, &rssi);
18845
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018846 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18847 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
18848 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018849 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
18850 hdd_wlan_get_freq(channel, &freq);
18851
18852
18853 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
18854 {
18855 if (NULL == wiphy->bands[i])
18856 {
18857 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
18858 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
18859 continue;
18860 }
18861
18862 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
18863 {
18864 struct ieee80211_supported_band *band = wiphy->bands[i];
18865
18866 if (band->channels[j].center_freq == (v_U16_t)freq)
18867 {
18868 survey->channel = &band->channels[j];
18869 /* The Rx BDs contain SNR values in dB for the received frames
18870 * while the supplicant expects noise. So we calculate and
18871 * return the value of noise (dBm)
18872 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
18873 */
18874 survey->noise = rssi - snr;
18875 survey->filled = SURVEY_INFO_NOISE_DBM;
18876 filled = 1;
18877 }
18878 }
18879 }
18880
18881 if (filled)
18882 pAdapter->survey_idx = 1;
18883 else
18884 {
18885 pAdapter->survey_idx = 0;
18886 return -ENONET;
18887 }
18888
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018889 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018890 return 0;
18891}
18892
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018893static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
18894 struct net_device *dev,
18895 int idx, struct survey_info *survey)
18896{
18897 int ret;
18898
18899 vos_ssr_protect(__func__);
18900 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
18901 vos_ssr_unprotect(__func__);
18902
18903 return ret;
18904}
18905
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018906/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018907 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018908 * this is called when cfg80211 driver resume
18909 * driver updates latest sched_scan scan result(if any) to cfg80211 database
18910 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018911int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018912{
18913 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18914 hdd_adapter_t *pAdapter;
18915 hdd_adapter_list_node_t *pAdapterNode, *pNext;
18916 VOS_STATUS status = VOS_STATUS_SUCCESS;
18917
18918 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018919
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018920 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018921 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018922 return 0;
18923 }
18924
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018925 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
18926 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018927 spin_lock(&pHddCtx->schedScan_lock);
18928 pHddCtx->isWiphySuspended = FALSE;
18929 if (TRUE != pHddCtx->isSchedScanUpdatePending)
18930 {
18931 spin_unlock(&pHddCtx->schedScan_lock);
18932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18933 "%s: Return resume is not due to PNO indication", __func__);
18934 return 0;
18935 }
18936 // Reset flag to avoid updatating cfg80211 data old results again
18937 pHddCtx->isSchedScanUpdatePending = FALSE;
18938 spin_unlock(&pHddCtx->schedScan_lock);
18939
18940 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
18941
18942 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
18943 {
18944 pAdapter = pAdapterNode->pAdapter;
18945 if ( (NULL != pAdapter) &&
18946 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
18947 {
18948 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018949 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018950 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18951 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018952 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018953 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018954 {
18955 /* Acquire wakelock to handle the case where APP's tries to
18956 * suspend immediately after updating the scan results. Whis
18957 * results in app's is in suspended state and not able to
18958 * process the connect request to AP
18959 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053018960 hdd_prevent_suspend_timeout(2000,
18961 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018962 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018963 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018964
18965 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18966 "%s : cfg80211 scan result database updated", __func__);
18967
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018968 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018969 return 0;
18970
18971 }
18972 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18973 pAdapterNode = pNext;
18974 }
18975
18976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18977 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018978 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018979 return 0;
18980}
18981
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018982int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
18983{
18984 int ret;
18985
18986 vos_ssr_protect(__func__);
18987 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
18988 vos_ssr_unprotect(__func__);
18989
18990 return ret;
18991}
18992
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018993/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018994 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018995 * this is called when cfg80211 driver suspends
18996 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018997int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018998 struct cfg80211_wowlan *wow)
18999{
19000 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019001 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019002
19003 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019004
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019005 ret = wlan_hdd_validate_context(pHddCtx);
19006 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019007 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019008 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019009 }
19010
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019011
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019012 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19013 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
19014 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019015 pHddCtx->isWiphySuspended = TRUE;
19016
19017 EXIT();
19018
19019 return 0;
19020}
19021
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019022int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19023 struct cfg80211_wowlan *wow)
19024{
19025 int ret;
19026
19027 vos_ssr_protect(__func__);
19028 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19029 vos_ssr_unprotect(__func__);
19030
19031 return ret;
19032}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019033
19034#ifdef FEATURE_OEM_DATA_SUPPORT
19035static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
19036 void *pMsg)
19037{
19038 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19039
19040 ENTER();
19041
19042 if (wlan_hdd_validate_context(pHddCtx)) {
19043 return;
19044 }
19045 if (!pMsg)
19046 {
19047 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
19048 return;
19049 }
19050
19051 send_oem_data_rsp_msg(sizeof(tOemDataRspNew), pMsg);
19052
19053 EXIT();
19054 return;
19055
19056}
19057
19058void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
19059 void *pMsg)
19060{
19061 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19062
19063 ENTER();
19064
19065 if (wlan_hdd_validate_context(pHddCtx)) {
19066 return;
19067 }
19068
19069 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
19070
19071 switch(evType) {
19072 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
19073 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg);
19074 break;
19075 default:
19076 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
19077 break;
19078 }
19079 EXIT();
19080}
19081#endif
19082
Jeff Johnson295189b2012-06-20 16:38:30 -070019083/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019084static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070019085{
19086 .add_virtual_intf = wlan_hdd_add_virtual_intf,
19087 .del_virtual_intf = wlan_hdd_del_virtual_intf,
19088 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
19089 .change_station = wlan_hdd_change_station,
19090#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
19091 .add_beacon = wlan_hdd_cfg80211_add_beacon,
19092 .del_beacon = wlan_hdd_cfg80211_del_beacon,
19093 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019094#else
19095 .start_ap = wlan_hdd_cfg80211_start_ap,
19096 .change_beacon = wlan_hdd_cfg80211_change_beacon,
19097 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070019098#endif
19099 .change_bss = wlan_hdd_cfg80211_change_bss,
19100 .add_key = wlan_hdd_cfg80211_add_key,
19101 .get_key = wlan_hdd_cfg80211_get_key,
19102 .del_key = wlan_hdd_cfg80211_del_key,
19103 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019104#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070019105 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019106#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019107 .scan = wlan_hdd_cfg80211_scan,
19108 .connect = wlan_hdd_cfg80211_connect,
19109 .disconnect = wlan_hdd_cfg80211_disconnect,
19110 .join_ibss = wlan_hdd_cfg80211_join_ibss,
19111 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
19112 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
19113 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
19114 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070019115 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
19116 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053019117 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070019118#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19119 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
19120 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
19121 .set_txq_params = wlan_hdd_set_txq_params,
19122#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019123 .get_station = wlan_hdd_cfg80211_get_station,
19124 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
19125 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019126 .add_station = wlan_hdd_cfg80211_add_station,
19127#ifdef FEATURE_WLAN_LFR
19128 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
19129 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
19130 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
19131#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019132#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
19133 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
19134#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019135#ifdef FEATURE_WLAN_TDLS
19136 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
19137 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
19138#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019139#ifdef WLAN_FEATURE_GTK_OFFLOAD
19140 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
19141#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019142#ifdef FEATURE_WLAN_SCAN_PNO
19143 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
19144 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
19145#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019146 .resume = wlan_hdd_cfg80211_resume_wlan,
19147 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019148 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070019149#ifdef WLAN_NL80211_TESTMODE
19150 .testmode_cmd = wlan_hdd_cfg80211_testmode,
19151#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019152 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070019153};
19154