blob: 7be452791f11f7f93b52caa178ae26b13476c3ed [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Masti, Narayanraddie1892a52015-12-15 15:01:01 +05302 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530100
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
102#define g_mode_rates_size (12)
103#define a_mode_rates_size (8)
104#define FREQ_BASE_80211G (2407)
105#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700106#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530107#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800109 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700110
111#define HDD2GHZCHAN(freq, chan, flag) { \
112 .band = IEEE80211_BAND_2GHZ, \
113 .center_freq = (freq), \
114 .hw_value = (chan),\
115 .flags = (flag), \
116 .max_antenna_gain = 0 ,\
117 .max_power = 30, \
118}
119
120#define HDD5GHZCHAN(freq, chan, flag) { \
121 .band = IEEE80211_BAND_5GHZ, \
122 .center_freq = (freq), \
123 .hw_value = (chan),\
124 .flags = (flag), \
125 .max_antenna_gain = 0 ,\
126 .max_power = 30, \
127}
128
129#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
130{\
131 .bitrate = rate, \
132 .hw_value = rate_id, \
133 .flags = flag, \
134}
135
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530136#ifdef WLAN_FEATURE_VOWIFI_11R
137#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
138#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
139#endif
140
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530141#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530142#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143
Sunil Duttc69bccb2014-05-26 21:30:20 +0530144#ifdef WLAN_FEATURE_LINK_LAYER_STATS
145/*
146 * Used to allocate the size of 4096 for the link layer stats.
147 * The size of 4096 is considered assuming that all data per
148 * respective event fit with in the limit.Please take a call
149 * on the limit based on the data requirements on link layer
150 * statistics.
151 */
152#define LL_STATS_EVENT_BUF_SIZE 4096
153#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530154#ifdef WLAN_FEATURE_EXTSCAN
155/*
156 * Used to allocate the size of 4096 for the EXTScan NL data.
157 * The size of 4096 is considered assuming that all data per
158 * respective event fit with in the limit.Please take a call
159 * on the limit based on the data requirements.
160 */
161
162#define EXTSCAN_EVENT_BUF_SIZE 4096
163#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
164#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530165
Atul Mittal115287b2014-07-08 13:26:33 +0530166/*EXT TDLS*/
167/*
168 * Used to allocate the size of 4096 for the TDLS.
169 * The size of 4096 is considered assuming that all data per
170 * respective event fit with in the limit.Please take a call
171 * on the limit based on the data requirements on link layer
172 * statistics.
173 */
174#define EXTTDLS_EVENT_BUF_SIZE 4096
175
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530176/*
177 * Values for Mac spoofing feature
178 *
179 */
180#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
181#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
182#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530183#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
184
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530185
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530186static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700187{
188 WLAN_CIPHER_SUITE_WEP40,
189 WLAN_CIPHER_SUITE_WEP104,
190 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800191#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700192#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
193 WLAN_CIPHER_SUITE_KRK,
194 WLAN_CIPHER_SUITE_CCMP,
195#else
196 WLAN_CIPHER_SUITE_CCMP,
197#endif
198#ifdef FEATURE_WLAN_WAPI
199 WLAN_CIPHER_SUITE_SMS4,
200#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700201#ifdef WLAN_FEATURE_11W
202 WLAN_CIPHER_SUITE_AES_CMAC,
203#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700204};
205
206static inline int is_broadcast_ether_addr(const u8 *addr)
207{
208 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
209 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
210}
211
Agrawal Ashish97dec502015-11-26 20:20:58 +0530212const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530213{
Jeff Johnson295189b2012-06-20 16:38:30 -0700214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2417, 2, 0) ,
216 HDD2GHZCHAN(2422, 3, 0) ,
217 HDD2GHZCHAN(2427, 4, 0) ,
218 HDD2GHZCHAN(2432, 5, 0) ,
219 HDD2GHZCHAN(2437, 6, 0) ,
220 HDD2GHZCHAN(2442, 7, 0) ,
221 HDD2GHZCHAN(2447, 8, 0) ,
222 HDD2GHZCHAN(2452, 9, 0) ,
223 HDD2GHZCHAN(2457, 10, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225 HDD2GHZCHAN(2467, 12, 0) ,
226 HDD2GHZCHAN(2472, 13, 0) ,
227 HDD2GHZCHAN(2484, 14, 0) ,
228};
229
Agrawal Ashish97dec502015-11-26 20:20:58 +0530230const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700231{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700232 HDD5GHZCHAN(4920, 240, 0) ,
233 HDD5GHZCHAN(4940, 244, 0) ,
234 HDD5GHZCHAN(4960, 248, 0) ,
235 HDD5GHZCHAN(4980, 252, 0) ,
236 HDD5GHZCHAN(5040, 208, 0) ,
237 HDD5GHZCHAN(5060, 212, 0) ,
238 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD5GHZCHAN(5180, 36, 0) ,
240 HDD5GHZCHAN(5200, 40, 0) ,
241 HDD5GHZCHAN(5220, 44, 0) ,
242 HDD5GHZCHAN(5240, 48, 0) ,
243 HDD5GHZCHAN(5260, 52, 0) ,
244 HDD5GHZCHAN(5280, 56, 0) ,
245 HDD5GHZCHAN(5300, 60, 0) ,
246 HDD5GHZCHAN(5320, 64, 0) ,
247 HDD5GHZCHAN(5500,100, 0) ,
248 HDD5GHZCHAN(5520,104, 0) ,
249 HDD5GHZCHAN(5540,108, 0) ,
250 HDD5GHZCHAN(5560,112, 0) ,
251 HDD5GHZCHAN(5580,116, 0) ,
252 HDD5GHZCHAN(5600,120, 0) ,
253 HDD5GHZCHAN(5620,124, 0) ,
254 HDD5GHZCHAN(5640,128, 0) ,
255 HDD5GHZCHAN(5660,132, 0) ,
256 HDD5GHZCHAN(5680,136, 0) ,
257 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800258#ifdef FEATURE_WLAN_CH144
259 HDD5GHZCHAN(5720,144, 0) ,
260#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 HDD5GHZCHAN(5745,149, 0) ,
262 HDD5GHZCHAN(5765,153, 0) ,
263 HDD5GHZCHAN(5785,157, 0) ,
264 HDD5GHZCHAN(5805,161, 0) ,
265 HDD5GHZCHAN(5825,165, 0) ,
266};
267
268static struct ieee80211_rate g_mode_rates[] =
269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530270 HDD_G_MODE_RATETAB(10, 0x1, 0),
271 HDD_G_MODE_RATETAB(20, 0x2, 0),
272 HDD_G_MODE_RATETAB(55, 0x4, 0),
273 HDD_G_MODE_RATETAB(110, 0x8, 0),
274 HDD_G_MODE_RATETAB(60, 0x10, 0),
275 HDD_G_MODE_RATETAB(90, 0x20, 0),
276 HDD_G_MODE_RATETAB(120, 0x40, 0),
277 HDD_G_MODE_RATETAB(180, 0x80, 0),
278 HDD_G_MODE_RATETAB(240, 0x100, 0),
279 HDD_G_MODE_RATETAB(360, 0x200, 0),
280 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282};
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
284static struct ieee80211_rate a_mode_rates[] =
285{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530286 HDD_G_MODE_RATETAB(60, 0x10, 0),
287 HDD_G_MODE_RATETAB(90, 0x20, 0),
288 HDD_G_MODE_RATETAB(120, 0x40, 0),
289 HDD_G_MODE_RATETAB(180, 0x80, 0),
290 HDD_G_MODE_RATETAB(240, 0x100, 0),
291 HDD_G_MODE_RATETAB(360, 0x200, 0),
292 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 HDD_G_MODE_RATETAB(540, 0x800, 0),
294};
295
296static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
297{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530298 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700299 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
300 .band = IEEE80211_BAND_2GHZ,
301 .bitrates = g_mode_rates,
302 .n_bitrates = g_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
308 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
309 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
310 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
311 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
312 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
313};
314
Jeff Johnson295189b2012-06-20 16:38:30 -0700315static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
316{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530317 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
319 .band = IEEE80211_BAND_5GHZ,
320 .bitrates = a_mode_rates,
321 .n_bitrates = a_mode_rates_size,
322 .ht_cap.ht_supported = 1,
323 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
324 | IEEE80211_HT_CAP_GRN_FLD
325 | IEEE80211_HT_CAP_DSSSCCK40
326 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
327 | IEEE80211_HT_CAP_SGI_40
328 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
329 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
330 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
331 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
332 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
333 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
334};
335
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530336/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 TX/RX direction for each kind of interface */
338static const struct ieee80211_txrx_stypes
339wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
340 [NL80211_IFTYPE_STATION] = {
341 .tx = 0xffff,
342 .rx = BIT(SIR_MAC_MGMT_ACTION) |
343 BIT(SIR_MAC_MGMT_PROBE_REQ),
344 },
345 [NL80211_IFTYPE_AP] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
348 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
349 BIT(SIR_MAC_MGMT_PROBE_REQ) |
350 BIT(SIR_MAC_MGMT_DISASSOC) |
351 BIT(SIR_MAC_MGMT_AUTH) |
352 BIT(SIR_MAC_MGMT_DEAUTH) |
353 BIT(SIR_MAC_MGMT_ACTION),
354 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700355 [NL80211_IFTYPE_ADHOC] = {
356 .tx = 0xffff,
357 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
358 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
359 BIT(SIR_MAC_MGMT_PROBE_REQ) |
360 BIT(SIR_MAC_MGMT_DISASSOC) |
361 BIT(SIR_MAC_MGMT_AUTH) |
362 BIT(SIR_MAC_MGMT_DEAUTH) |
363 BIT(SIR_MAC_MGMT_ACTION),
364 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 [NL80211_IFTYPE_P2P_CLIENT] = {
366 .tx = 0xffff,
367 .rx = BIT(SIR_MAC_MGMT_ACTION) |
368 BIT(SIR_MAC_MGMT_PROBE_REQ),
369 },
370 [NL80211_IFTYPE_P2P_GO] = {
371 /* This is also same as for SoftAP */
372 .tx = 0xffff,
373 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ) |
376 BIT(SIR_MAC_MGMT_DISASSOC) |
377 BIT(SIR_MAC_MGMT_AUTH) |
378 BIT(SIR_MAC_MGMT_DEAUTH) |
379 BIT(SIR_MAC_MGMT_ACTION),
380 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700381};
382
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800383#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800384static const struct ieee80211_iface_limit
385wlan_hdd_iface_limit[] = {
386 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800387 /* max = 3 ; Our driver create two interfaces during driver init
388 * wlan0 and p2p0 interfaces. p2p0 is considered as station
389 * interface until a group is formed. In JB architecture, once the
390 * group is formed, interface type of p2p0 is changed to P2P GO or
391 * Client.
392 * When supplicant remove the group, it first issue a set interface
393 * cmd to change the mode back to Station. In JB this works fine as
394 * we advertize two station type interface during driver init.
395 * Some vendors create separate interface for P2P GO/Client,
396 * after group formation(Third one). But while group remove
397 * supplicant first tries to change the mode(3rd interface) to STATION
398 * But as we advertized only two sta type interfaces nl80211 was
399 * returning error for the third one which was leading to failure in
400 * delete interface. Ideally while removing the group, supplicant
401 * should not try to change the 3rd interface mode to Station type.
402 * Till we get a fix in wpa_supplicant, we advertize max STA
403 * interface type to 3
404 */
405 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800406 .types = BIT(NL80211_IFTYPE_STATION),
407 },
408 {
409 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700410 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 },
412 {
413 .max = 1,
414 .types = BIT(NL80211_IFTYPE_P2P_GO) |
415 BIT(NL80211_IFTYPE_P2P_CLIENT),
416 },
417};
418
419/* By default, only single channel concurrency is allowed */
420static struct ieee80211_iface_combination
421wlan_hdd_iface_combination = {
422 .limits = wlan_hdd_iface_limit,
423 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800424 /*
425 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
426 * and p2p0 interfaces during driver init
427 * Some vendors create separate interface for P2P operations.
428 * wlan0: STA interface
429 * p2p0: P2P Device interface, action frames goes
430 * through this interface.
431 * p2p-xx: P2P interface, After GO negotiation this interface is
432 * created for p2p operations(GO/CLIENT interface).
433 */
434 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800435 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
436 .beacon_int_infra_match = false,
437};
438#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800439
Jeff Johnson295189b2012-06-20 16:38:30 -0700440static struct cfg80211_ops wlan_hdd_cfg80211_ops;
441
442/* Data rate 100KBPS based on IE Index */
443struct index_data_rate_type
444{
445 v_U8_t beacon_rate_index;
446 v_U16_t supported_rate[4];
447};
448
449/* 11B, 11G Rate table include Basic rate and Extended rate
450 The IDX field is the rate index
451 The HI field is the rate when RSSI is strong or being ignored
452 (in this case we report actual rate)
453 The MID field is the rate when RSSI is moderate
454 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
455 The LO field is the rate when RSSI is low
456 (in this case we don't report rates, actual current rate used)
457 */
458static const struct
459{
460 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700461 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700462} supported_data_rate[] =
463{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700464/* IDX HI HM LM LO (RSSI-based index */
465 {2, { 10, 10, 10, 0}},
466 {4, { 20, 20, 10, 0}},
467 {11, { 55, 20, 10, 0}},
468 {12, { 60, 55, 20, 0}},
469 {18, { 90, 55, 20, 0}},
470 {22, {110, 55, 20, 0}},
471 {24, {120, 90, 60, 0}},
472 {36, {180, 120, 60, 0}},
473 {44, {220, 180, 60, 0}},
474 {48, {240, 180, 90, 0}},
475 {66, {330, 180, 90, 0}},
476 {72, {360, 240, 90, 0}},
477 {96, {480, 240, 120, 0}},
478 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700479};
480
481/* MCS Based rate table */
482static struct index_data_rate_type supported_mcs_rate[] =
483{
484/* MCS L20 L40 S20 S40 */
485 {0, {65, 135, 72, 150}},
486 {1, {130, 270, 144, 300}},
487 {2, {195, 405, 217, 450}},
488 {3, {260, 540, 289, 600}},
489 {4, {390, 810, 433, 900}},
490 {5, {520, 1080, 578, 1200}},
491 {6, {585, 1215, 650, 1350}},
492 {7, {650, 1350, 722, 1500}}
493};
494
Leo Chang6f8870f2013-03-26 18:11:36 -0700495#ifdef WLAN_FEATURE_11AC
496
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530497#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700498
499struct index_vht_data_rate_type
500{
501 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530502 v_U16_t supported_VHT80_rate[2];
503 v_U16_t supported_VHT40_rate[2];
504 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700505};
506
507typedef enum
508{
509 DATA_RATE_11AC_MAX_MCS_7,
510 DATA_RATE_11AC_MAX_MCS_8,
511 DATA_RATE_11AC_MAX_MCS_9,
512 DATA_RATE_11AC_MAX_MCS_NA
513} eDataRate11ACMaxMcs;
514
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530515/* SSID broadcast type */
516typedef enum eSSIDBcastType
517{
518 eBCAST_UNKNOWN = 0,
519 eBCAST_NORMAL = 1,
520 eBCAST_HIDDEN = 2,
521} tSSIDBcastType;
522
Leo Chang6f8870f2013-03-26 18:11:36 -0700523/* MCS Based VHT rate table */
524static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
525{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530526/* MCS L80 S80 L40 S40 L20 S40*/
527 {0, {293, 325}, {135, 150}, {65, 72}},
528 {1, {585, 650}, {270, 300}, {130, 144}},
529 {2, {878, 975}, {405, 450}, {195, 217}},
530 {3, {1170, 1300}, {540, 600}, {260, 289}},
531 {4, {1755, 1950}, {810, 900}, {390, 433}},
532 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
533 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
534 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
535 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
536 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700537};
538#endif /* WLAN_FEATURE_11AC */
539
c_hpothu79aab322014-07-14 21:11:01 +0530540/*array index points to MCS and array value points respective rssi*/
541static int rssiMcsTbl[][10] =
542{
543/*MCS 0 1 2 3 4 5 6 7 8 9*/
544 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
545 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
546 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
547};
548
Jeff Johnson295189b2012-06-20 16:38:30 -0700549extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530550#ifdef FEATURE_WLAN_SCAN_PNO
551static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
552#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700553
Leo Chang9056f462013-08-01 19:21:11 -0700554#ifdef WLAN_NL80211_TESTMODE
555enum wlan_hdd_tm_attr
556{
557 WLAN_HDD_TM_ATTR_INVALID = 0,
558 WLAN_HDD_TM_ATTR_CMD = 1,
559 WLAN_HDD_TM_ATTR_DATA = 2,
560 WLAN_HDD_TM_ATTR_TYPE = 3,
561 /* keep last */
562 WLAN_HDD_TM_ATTR_AFTER_LAST,
563 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
564};
565
566enum wlan_hdd_tm_cmd
567{
568 WLAN_HDD_TM_CMD_WLAN_HB = 1,
569};
570
571#define WLAN_HDD_TM_DATA_MAX_LEN 5000
572
573static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
574{
575 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
576 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
577 .len = WLAN_HDD_TM_DATA_MAX_LEN },
578};
579#endif /* WLAN_NL80211_TESTMODE */
580
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800581#ifdef FEATURE_WLAN_CH_AVOID
582/*
583 * FUNCTION: wlan_hdd_send_avoid_freq_event
584 * This is called when wlan driver needs to send vendor specific
585 * avoid frequency range event to userspace
586 */
587int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
588 tHddAvoidFreqList *pAvoidFreqList)
589{
590 struct sk_buff *vendor_event;
591
592 ENTER();
593
594 if (!pHddCtx)
595 {
596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
597 "%s: HDD context is null", __func__);
598 return -1;
599 }
600
601 if (!pAvoidFreqList)
602 {
603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
604 "%s: pAvoidFreqList is null", __func__);
605 return -1;
606 }
607
608 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530609#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
610 NULL,
611#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800612 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530613 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800614 GFP_KERNEL);
615 if (!vendor_event)
616 {
617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
618 "%s: cfg80211_vendor_event_alloc failed", __func__);
619 return -1;
620 }
621
622 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
623 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
624
625 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
626
627 EXIT();
628 return 0;
629}
630#endif /* FEATURE_WLAN_CH_AVOID */
631
Srinivas Dasari030bad32015-02-18 23:23:54 +0530632/*
633 * FUNCTION: __wlan_hdd_cfg80211_nan_request
634 * This is called when wlan driver needs to send vendor specific
635 * nan request event.
636 */
637static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
638 struct wireless_dev *wdev,
639 const void *data, int data_len)
640{
641 tNanRequestReq nan_req;
642 VOS_STATUS status;
643 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530644 struct net_device *dev = wdev->netdev;
645 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
646 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530647 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
648
649 if (0 == data_len)
650 {
651 hddLog(VOS_TRACE_LEVEL_ERROR,
652 FL("NAN - Invalid Request, length = 0"));
653 return ret_val;
654 }
655
656 if (NULL == data)
657 {
658 hddLog(VOS_TRACE_LEVEL_ERROR,
659 FL("NAN - Invalid Request, data is NULL"));
660 return ret_val;
661 }
662
663 status = wlan_hdd_validate_context(pHddCtx);
664 if (0 != status)
665 {
666 hddLog(VOS_TRACE_LEVEL_ERROR,
667 FL("HDD context is not valid"));
668 return -EINVAL;
669 }
670
671 hddLog(LOG1, FL("Received NAN command"));
672 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
673 (tANI_U8 *)data, data_len);
674
675 /* check the NAN Capability */
676 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
677 {
678 hddLog(VOS_TRACE_LEVEL_ERROR,
679 FL("NAN is not supported by Firmware"));
680 return -EINVAL;
681 }
682
683 nan_req.request_data_len = data_len;
684 nan_req.request_data = data;
685
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530686 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530687 if (VOS_STATUS_SUCCESS == status)
688 {
689 ret_val = 0;
690 }
691 return ret_val;
692}
693
694/*
695 * FUNCTION: wlan_hdd_cfg80211_nan_request
696 * Wrapper to protect the nan vendor command from ssr
697 */
698static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
699 struct wireless_dev *wdev,
700 const void *data, int data_len)
701{
702 int ret;
703
704 vos_ssr_protect(__func__);
705 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
706 vos_ssr_unprotect(__func__);
707
708 return ret;
709}
710
711/*
712 * FUNCTION: wlan_hdd_cfg80211_nan_callback
713 * This is a callback function and it gets called
714 * when we need to report nan response event to
715 * upper layers.
716 */
717static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
718{
719 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
720 struct sk_buff *vendor_event;
721 int status;
722 tSirNanEvent *data;
723
724 ENTER();
725 if (NULL == msg)
726 {
727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
728 FL(" msg received here is null"));
729 return;
730 }
731 data = msg;
732
733 status = wlan_hdd_validate_context(pHddCtx);
734
735 if (0 != status)
736 {
737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
738 FL("HDD context is not valid"));
739 return;
740 }
741
742 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530743#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
744 NULL,
745#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530746 data->event_data_len +
747 NLMSG_HDRLEN,
748 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
749 GFP_KERNEL);
750
751 if (!vendor_event)
752 {
753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
754 FL("cfg80211_vendor_event_alloc failed"));
755 return;
756 }
757 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
758 data->event_data_len, data->event_data))
759 {
760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
761 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
762 kfree_skb(vendor_event);
763 return;
764 }
765 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
766 EXIT();
767}
768
769/*
770 * FUNCTION: wlan_hdd_cfg80211_nan_init
771 * This function is called to register the callback to sme layer
772 */
773inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
774{
775 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
776}
777
778
Sunil Duttc69bccb2014-05-26 21:30:20 +0530779#ifdef WLAN_FEATURE_LINK_LAYER_STATS
780
781static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
782 struct sk_buff *vendor_event)
783{
784 if (nla_put_u8(vendor_event,
785 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
786 stats->rate.preamble) ||
787 nla_put_u8(vendor_event,
788 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
789 stats->rate.nss) ||
790 nla_put_u8(vendor_event,
791 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
792 stats->rate.bw) ||
793 nla_put_u8(vendor_event,
794 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
795 stats->rate.rateMcsIdx) ||
796 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
797 stats->rate.bitrate ) ||
798 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
799 stats->txMpdu ) ||
800 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
801 stats->rxMpdu ) ||
802 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
803 stats->mpduLost ) ||
804 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
805 stats->retries) ||
806 nla_put_u32(vendor_event,
807 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
808 stats->retriesShort ) ||
809 nla_put_u32(vendor_event,
810 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
811 stats->retriesLong))
812 {
813 hddLog(VOS_TRACE_LEVEL_ERROR,
814 FL("QCA_WLAN_VENDOR_ATTR put fail"));
815 return FALSE;
816 }
817 return TRUE;
818}
819
820static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
821 struct sk_buff *vendor_event)
822{
823 u32 i = 0;
824 struct nlattr *rateInfo;
825 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
826 stats->type) ||
827 nla_put(vendor_event,
828 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
829 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
830 nla_put_u32(vendor_event,
831 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
832 stats->capabilities) ||
833 nla_put_u32(vendor_event,
834 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
835 stats->numRate))
836 {
837 hddLog(VOS_TRACE_LEVEL_ERROR,
838 FL("QCA_WLAN_VENDOR_ATTR put fail"));
839 goto error;
840 }
841
842 rateInfo = nla_nest_start(vendor_event,
843 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530844 if(!rateInfo)
845 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530846 for (i = 0; i < stats->numRate; i++)
847 {
848 struct nlattr *rates;
849 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
850 stats->rateStats +
851 (i * sizeof(tSirWifiRateStat)));
852 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530853 if(!rates)
854 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530855
856 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
857 {
858 hddLog(VOS_TRACE_LEVEL_ERROR,
859 FL("QCA_WLAN_VENDOR_ATTR put fail"));
860 return FALSE;
861 }
862 nla_nest_end(vendor_event, rates);
863 }
864 nla_nest_end(vendor_event, rateInfo);
865
866 return TRUE;
867error:
868 return FALSE;
869}
870
871static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
872 struct sk_buff *vendor_event)
873{
874 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
875 stats->ac ) ||
876 nla_put_u32(vendor_event,
877 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
878 stats->txMpdu ) ||
879 nla_put_u32(vendor_event,
880 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
881 stats->rxMpdu ) ||
882 nla_put_u32(vendor_event,
883 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
884 stats->txMcast ) ||
885 nla_put_u32(vendor_event,
886 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
887 stats->rxMcast ) ||
888 nla_put_u32(vendor_event,
889 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
890 stats->rxAmpdu ) ||
891 nla_put_u32(vendor_event,
892 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
893 stats->txAmpdu ) ||
894 nla_put_u32(vendor_event,
895 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
896 stats->mpduLost )||
897 nla_put_u32(vendor_event,
898 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
899 stats->retries ) ||
900 nla_put_u32(vendor_event,
901 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
902 stats->retriesShort ) ||
903 nla_put_u32(vendor_event,
904 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
905 stats->retriesLong ) ||
906 nla_put_u32(vendor_event,
907 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
908 stats->contentionTimeMin ) ||
909 nla_put_u32(vendor_event,
910 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
911 stats->contentionTimeMax ) ||
912 nla_put_u32(vendor_event,
913 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
914 stats->contentionTimeAvg ) ||
915 nla_put_u32(vendor_event,
916 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
917 stats->contentionNumSamples ))
918 {
919 hddLog(VOS_TRACE_LEVEL_ERROR,
920 FL("QCA_WLAN_VENDOR_ATTR put fail") );
921 return FALSE;
922 }
923 return TRUE;
924}
925
926static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
927 struct sk_buff *vendor_event)
928{
Dino Myclec8f3f332014-07-21 16:48:27 +0530929 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530930 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
931 nla_put(vendor_event,
932 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
933 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
934 nla_put_u32(vendor_event,
935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
936 stats->state ) ||
937 nla_put_u32(vendor_event,
938 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
939 stats->roaming ) ||
940 nla_put_u32(vendor_event,
941 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
942 stats->capabilities ) ||
943 nla_put(vendor_event,
944 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
945 strlen(stats->ssid), stats->ssid) ||
946 nla_put(vendor_event,
947 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
948 WNI_CFG_BSSID_LEN, stats->bssid) ||
949 nla_put(vendor_event,
950 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
951 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
952 nla_put(vendor_event,
953 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
954 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
955 )
956 {
957 hddLog(VOS_TRACE_LEVEL_ERROR,
958 FL("QCA_WLAN_VENDOR_ATTR put fail") );
959 return FALSE;
960 }
961 return TRUE;
962}
963
Dino Mycle3b9536d2014-07-09 22:05:24 +0530964static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
965 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530966 struct sk_buff *vendor_event)
967{
968 int i = 0;
969 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530970 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
971 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530972 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530973
Sunil Duttc69bccb2014-05-26 21:30:20 +0530974 if (FALSE == put_wifi_interface_info(
975 &pWifiIfaceStat->info,
976 vendor_event))
977 {
978 hddLog(VOS_TRACE_LEVEL_ERROR,
979 FL("QCA_WLAN_VENDOR_ATTR put fail") );
980 return FALSE;
981
982 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530983 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
984 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
985 if (NULL == pWifiIfaceStatTL)
986 {
987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
988 return FALSE;
989 }
990
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530991 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
992 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
993 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
994 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
995
996 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
997 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
998 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
999 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301000
1001 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1002 {
1003 if (VOS_STATUS_SUCCESS ==
1004 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1005 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1006 {
1007 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1008 * obtained from TL structure
1009 */
1010
1011 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1012 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301013 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1014
Srinivas Dasari98947432014-11-07 19:41:24 +05301015 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1016 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1017 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1018 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1019 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1020 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1021 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1022 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301023
Srinivas Dasari98947432014-11-07 19:41:24 +05301024 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1025 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1026 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1027 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1028 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1029 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1030 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1031 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301032
Srinivas Dasari98947432014-11-07 19:41:24 +05301033 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1034 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1035 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1036 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1037 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1038 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1039 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1040 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301041 }
1042 else
1043 {
1044 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1045 }
1046
Dino Mycle3b9536d2014-07-09 22:05:24 +05301047 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1048 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1049 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1050 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1051 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1052 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1053 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1054 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1055 }
1056 else
1057 {
1058 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1059 }
1060
1061
Sunil Duttc69bccb2014-05-26 21:30:20 +05301062
1063 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301064 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1065 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1066 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301067 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1068 pWifiIfaceStat->beaconRx) ||
1069 nla_put_u32(vendor_event,
1070 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1071 pWifiIfaceStat->mgmtRx) ||
1072 nla_put_u32(vendor_event,
1073 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1074 pWifiIfaceStat->mgmtActionRx) ||
1075 nla_put_u32(vendor_event,
1076 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1077 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301078 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301079 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1080 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301081 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301082 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1083 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301084 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301085 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1086 pWifiIfaceStat->rssiAck))
1087 {
1088 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301089 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1090 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301091 return FALSE;
1092 }
1093
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301094#ifdef FEATURE_EXT_LL_STAT
1095 /*
1096 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1097 * then host should send Leaky AP stats to upper layer,
1098 * otherwise no need to send these stats.
1099 */
1100 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1101 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1102 )
1103 {
1104 hddLog(VOS_TRACE_LEVEL_INFO,
1105 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1106 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1107 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1108 pWifiIfaceStat->leakyApStat.rx_leak_window,
1109 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1110 if (nla_put_u32(vendor_event,
1111 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1112 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1113 nla_put_u32(vendor_event,
1114 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1115 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1116 nla_put_u32(vendor_event,
1117 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1118 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1119 nla_put_u64(vendor_event,
1120 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1121 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1122 {
1123 hddLog(VOS_TRACE_LEVEL_ERROR,
1124 FL("EXT_LL_STAT put fail"));
1125 vos_mem_free(pWifiIfaceStatTL);
1126 return FALSE;
1127 }
1128 }
1129#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301130 wmmInfo = nla_nest_start(vendor_event,
1131 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301132 if(!wmmInfo)
1133 {
1134 vos_mem_free(pWifiIfaceStatTL);
1135 return FALSE;
1136 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301137 for (i = 0; i < WIFI_AC_MAX; i++)
1138 {
1139 struct nlattr *wmmStats;
1140 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301141 if(!wmmStats)
1142 {
1143 vos_mem_free(pWifiIfaceStatTL);
1144 return FALSE;
1145 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301146 if (FALSE == put_wifi_wmm_ac_stat(
1147 &pWifiIfaceStat->AccessclassStats[i],
1148 vendor_event))
1149 {
1150 hddLog(VOS_TRACE_LEVEL_ERROR,
1151 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301152 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301153 return FALSE;
1154 }
1155
1156 nla_nest_end(vendor_event, wmmStats);
1157 }
1158 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301159 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301160 return TRUE;
1161}
1162
1163static tSirWifiInterfaceMode
1164 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1165{
1166 switch (deviceMode)
1167 {
1168 case WLAN_HDD_INFRA_STATION:
1169 return WIFI_INTERFACE_STA;
1170 case WLAN_HDD_SOFTAP:
1171 return WIFI_INTERFACE_SOFTAP;
1172 case WLAN_HDD_P2P_CLIENT:
1173 return WIFI_INTERFACE_P2P_CLIENT;
1174 case WLAN_HDD_P2P_GO:
1175 return WIFI_INTERFACE_P2P_GO;
1176 case WLAN_HDD_IBSS:
1177 return WIFI_INTERFACE_IBSS;
1178 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301179 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301180 }
1181}
1182
1183static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1184 tpSirWifiInterfaceInfo pInfo)
1185{
1186 v_U8_t *staMac = NULL;
1187 hdd_station_ctx_t *pHddStaCtx;
1188 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1189 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1190
1191 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1192
1193 vos_mem_copy(pInfo->macAddr,
1194 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1195
1196 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1197 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1198 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1199 {
1200 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1201 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1202 {
1203 pInfo->state = WIFI_DISCONNECTED;
1204 }
1205 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1206 {
1207 hddLog(VOS_TRACE_LEVEL_ERROR,
1208 "%s: Session ID %d, Connection is in progress", __func__,
1209 pAdapter->sessionId);
1210 pInfo->state = WIFI_ASSOCIATING;
1211 }
1212 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1213 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1214 {
1215 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1216 hddLog(VOS_TRACE_LEVEL_ERROR,
1217 "%s: client " MAC_ADDRESS_STR
1218 " is in the middle of WPS/EAPOL exchange.", __func__,
1219 MAC_ADDR_ARRAY(staMac));
1220 pInfo->state = WIFI_AUTHENTICATING;
1221 }
1222 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1223 {
1224 pInfo->state = WIFI_ASSOCIATED;
1225 vos_mem_copy(pInfo->bssid,
1226 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1227 vos_mem_copy(pInfo->ssid,
1228 pHddStaCtx->conn_info.SSID.SSID.ssId,
1229 pHddStaCtx->conn_info.SSID.SSID.length);
1230 //NULL Terminate the string.
1231 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1232 }
1233 }
1234 vos_mem_copy(pInfo->countryStr,
1235 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1236
1237 vos_mem_copy(pInfo->apCountryStr,
1238 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1239
1240 return TRUE;
1241}
1242
1243/*
1244 * hdd_link_layer_process_peer_stats () - This function is called after
1245 * receiving Link Layer Peer statistics from FW.This function converts
1246 * the firmware data to the NL data and sends the same to the kernel/upper
1247 * layers.
1248 */
1249static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1250 v_VOID_t *pData)
1251{
1252 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301253 tpSirWifiPeerStat pWifiPeerStat;
1254 tpSirWifiPeerInfo pWifiPeerInfo;
1255 struct nlattr *peerInfo;
1256 struct sk_buff *vendor_event;
1257 int status, i;
1258
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301259 ENTER();
1260
Sunil Duttc69bccb2014-05-26 21:30:20 +05301261 status = wlan_hdd_validate_context(pHddCtx);
1262 if (0 != status)
1263 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301264 return;
1265 }
1266
1267 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1268
1269 hddLog(VOS_TRACE_LEVEL_INFO,
1270 "LL_STATS_PEER_ALL : numPeers %u",
1271 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301272 /*
1273 * Allocate a size of 4096 for the peer stats comprising
1274 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1275 * sizeof (tSirWifiRateStat).Each field is put with an
1276 * NL attribute.The size of 4096 is considered assuming
1277 * that number of rates shall not exceed beyond 50 with
1278 * the sizeof (tSirWifiRateStat) being 32.
1279 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301280 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1281 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301282 if (!vendor_event)
1283 {
1284 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301285 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301286 __func__);
1287 return;
1288 }
1289 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301290 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1291 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1292 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301293 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1294 pWifiPeerStat->numPeers))
1295 {
1296 hddLog(VOS_TRACE_LEVEL_ERROR,
1297 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1298 kfree_skb(vendor_event);
1299 return;
1300 }
1301
1302 peerInfo = nla_nest_start(vendor_event,
1303 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301304 if(!peerInfo)
1305 {
1306 hddLog(VOS_TRACE_LEVEL_ERROR,
1307 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1308 __func__);
1309 kfree_skb(vendor_event);
1310 return;
1311 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301312
1313 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1314 pWifiPeerStat->peerInfo);
1315
1316 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1317 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301318 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301319 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301320
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301321 if(!peers)
1322 {
1323 hddLog(VOS_TRACE_LEVEL_ERROR,
1324 "%s: peer stats put fail",
1325 __func__);
1326 kfree_skb(vendor_event);
1327 return;
1328 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301329 if (FALSE == put_wifi_peer_info(
1330 pWifiPeerInfo, vendor_event))
1331 {
1332 hddLog(VOS_TRACE_LEVEL_ERROR,
1333 "%s: put_wifi_peer_info put fail", __func__);
1334 kfree_skb(vendor_event);
1335 return;
1336 }
1337
1338 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1339 pWifiPeerStat->peerInfo +
1340 (i * sizeof(tSirWifiPeerInfo)) +
1341 (numRate * sizeof (tSirWifiRateStat)));
1342 nla_nest_end(vendor_event, peers);
1343 }
1344 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301345 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301346 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301347}
1348
1349/*
1350 * hdd_link_layer_process_iface_stats () - This function is called after
1351 * receiving Link Layer Interface statistics from FW.This function converts
1352 * the firmware data to the NL data and sends the same to the kernel/upper
1353 * layers.
1354 */
1355static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1356 v_VOID_t *pData)
1357{
1358 tpSirWifiIfaceStat pWifiIfaceStat;
1359 struct sk_buff *vendor_event;
1360 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1361 int status;
1362
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301363 ENTER();
1364
Sunil Duttc69bccb2014-05-26 21:30:20 +05301365 status = wlan_hdd_validate_context(pHddCtx);
1366 if (0 != status)
1367 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301368 return;
1369 }
1370 /*
1371 * Allocate a size of 4096 for the interface stats comprising
1372 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1373 * assuming that all these fit with in the limit.Please take
1374 * a call on the limit based on the data requirements on
1375 * interface statistics.
1376 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301377 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1378 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301379 if (!vendor_event)
1380 {
1381 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301382 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301383 return;
1384 }
1385
1386 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1387
Dino Mycle3b9536d2014-07-09 22:05:24 +05301388
1389 if (FALSE == hdd_get_interface_info( pAdapter,
1390 &pWifiIfaceStat->info))
1391 {
1392 hddLog(VOS_TRACE_LEVEL_ERROR,
1393 FL("hdd_get_interface_info get fail") );
1394 kfree_skb(vendor_event);
1395 return;
1396 }
1397
1398 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1399 vendor_event))
1400 {
1401 hddLog(VOS_TRACE_LEVEL_ERROR,
1402 FL("put_wifi_iface_stats fail") );
1403 kfree_skb(vendor_event);
1404 return;
1405 }
1406
Sunil Duttc69bccb2014-05-26 21:30:20 +05301407 hddLog(VOS_TRACE_LEVEL_INFO,
1408 "WMI_LINK_STATS_IFACE Data");
1409
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301410 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301411
1412 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301413}
1414
1415/*
1416 * hdd_link_layer_process_radio_stats () - This function is called after
1417 * receiving Link Layer Radio statistics from FW.This function converts
1418 * the firmware data to the NL data and sends the same to the kernel/upper
1419 * layers.
1420 */
1421static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1422 v_VOID_t *pData)
1423{
1424 int status, i;
1425 tpSirWifiRadioStat pWifiRadioStat;
1426 tpSirWifiChannelStats pWifiChannelStats;
1427 struct sk_buff *vendor_event;
1428 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1429 struct nlattr *chList;
1430
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301431 ENTER();
1432
Sunil Duttc69bccb2014-05-26 21:30:20 +05301433 status = wlan_hdd_validate_context(pHddCtx);
1434 if (0 != status)
1435 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301436 return;
1437 }
1438 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1439
1440 hddLog(VOS_TRACE_LEVEL_INFO,
1441 "LL_STATS_RADIO"
1442 " radio is %d onTime is %u "
1443 " txTime is %u rxTime is %u "
1444 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301445 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301446 " onTimePnoScan is %u onTimeHs20 is %u "
1447 " numChannels is %u",
1448 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1449 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1450 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301451 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301452 pWifiRadioStat->onTimeRoamScan,
1453 pWifiRadioStat->onTimePnoScan,
1454 pWifiRadioStat->onTimeHs20,
1455 pWifiRadioStat->numChannels);
1456 /*
1457 * Allocate a size of 4096 for the Radio stats comprising
1458 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1459 * (tSirWifiChannelStats).Each channel data is put with an
1460 * NL attribute.The size of 4096 is considered assuming that
1461 * number of channels shall not exceed beyond 60 with the
1462 * sizeof (tSirWifiChannelStats) being 24 bytes.
1463 */
1464
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301465 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1466 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301467 if (!vendor_event)
1468 {
1469 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301470 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301471 return;
1472 }
1473
1474 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301475 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1476 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1477 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301478 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1479 pWifiRadioStat->radio) ||
1480 nla_put_u32(vendor_event,
1481 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1482 pWifiRadioStat->onTime) ||
1483 nla_put_u32(vendor_event,
1484 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1485 pWifiRadioStat->txTime) ||
1486 nla_put_u32(vendor_event,
1487 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1488 pWifiRadioStat->rxTime) ||
1489 nla_put_u32(vendor_event,
1490 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1491 pWifiRadioStat->onTimeScan) ||
1492 nla_put_u32(vendor_event,
1493 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1494 pWifiRadioStat->onTimeNbd) ||
1495 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301496 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1497 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301498 nla_put_u32(vendor_event,
1499 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1500 pWifiRadioStat->onTimeRoamScan) ||
1501 nla_put_u32(vendor_event,
1502 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1503 pWifiRadioStat->onTimePnoScan) ||
1504 nla_put_u32(vendor_event,
1505 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1506 pWifiRadioStat->onTimeHs20) ||
1507 nla_put_u32(vendor_event,
1508 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1509 pWifiRadioStat->numChannels))
1510 {
1511 hddLog(VOS_TRACE_LEVEL_ERROR,
1512 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1513 kfree_skb(vendor_event);
1514 return ;
1515 }
1516
1517 chList = nla_nest_start(vendor_event,
1518 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301519 if(!chList)
1520 {
1521 hddLog(VOS_TRACE_LEVEL_ERROR,
1522 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1523 __func__);
1524 kfree_skb(vendor_event);
1525 return;
1526 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301527 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1528 {
1529 struct nlattr *chInfo;
1530
1531 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1532 pWifiRadioStat->channels +
1533 (i * sizeof(tSirWifiChannelStats)));
1534
Sunil Duttc69bccb2014-05-26 21:30:20 +05301535 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301536 if(!chInfo)
1537 {
1538 hddLog(VOS_TRACE_LEVEL_ERROR,
1539 "%s: failed to put chInfo",
1540 __func__);
1541 kfree_skb(vendor_event);
1542 return;
1543 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301544
1545 if (nla_put_u32(vendor_event,
1546 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1547 pWifiChannelStats->channel.width) ||
1548 nla_put_u32(vendor_event,
1549 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1550 pWifiChannelStats->channel.centerFreq) ||
1551 nla_put_u32(vendor_event,
1552 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1553 pWifiChannelStats->channel.centerFreq0) ||
1554 nla_put_u32(vendor_event,
1555 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1556 pWifiChannelStats->channel.centerFreq1) ||
1557 nla_put_u32(vendor_event,
1558 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1559 pWifiChannelStats->onTime) ||
1560 nla_put_u32(vendor_event,
1561 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1562 pWifiChannelStats->ccaBusyTime))
1563 {
1564 hddLog(VOS_TRACE_LEVEL_ERROR,
1565 FL("cfg80211_vendor_event_alloc failed") );
1566 kfree_skb(vendor_event);
1567 return ;
1568 }
1569 nla_nest_end(vendor_event, chInfo);
1570 }
1571 nla_nest_end(vendor_event, chList);
1572
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301573 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301574
1575 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301576 return;
1577}
1578
1579/*
1580 * hdd_link_layer_stats_ind_callback () - This function is called after
1581 * receiving Link Layer indications from FW.This callback converts the firmware
1582 * data to the NL data and send the same to the kernel/upper layers.
1583 */
1584static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1585 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301586 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301587{
Dino Mycled3d50022014-07-07 12:58:25 +05301588 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1589 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301590 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301591 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301592 int status;
1593
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301594 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301595
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301596 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301597 if (0 != status)
1598 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301599 return;
1600 }
1601
Dino Mycled3d50022014-07-07 12:58:25 +05301602 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1603 if (NULL == pAdapter)
1604 {
1605 hddLog(VOS_TRACE_LEVEL_ERROR,
1606 FL(" MAC address %pM does not exist with host"),
1607 macAddr);
1608 return;
1609 }
1610
Sunil Duttc69bccb2014-05-26 21:30:20 +05301611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301612 "%s: Interface: %s LLStats indType: %d", __func__,
1613 pAdapter->dev->name, indType);
1614
Sunil Duttc69bccb2014-05-26 21:30:20 +05301615 switch (indType)
1616 {
1617 case SIR_HAL_LL_STATS_RESULTS_RSP:
1618 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301619 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301620 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1621 "respId = %u, moreResultToFollow = %u",
1622 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1623 macAddr, linkLayerStatsResults->respId,
1624 linkLayerStatsResults->moreResultToFollow);
1625
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301626 spin_lock(&hdd_context_lock);
1627 context = &pHddCtx->ll_stats_context;
1628 /* validate response received from target */
1629 if ((context->request_id != linkLayerStatsResults->respId) ||
1630 !(context->request_bitmap & linkLayerStatsResults->paramId))
1631 {
1632 spin_unlock(&hdd_context_lock);
1633 hddLog(LOGE,
1634 FL("Error : Request id %d response id %d request bitmap 0x%x"
1635 "response bitmap 0x%x"),
1636 context->request_id, linkLayerStatsResults->respId,
1637 context->request_bitmap, linkLayerStatsResults->paramId);
1638 return;
1639 }
1640 spin_unlock(&hdd_context_lock);
1641
Sunil Duttc69bccb2014-05-26 21:30:20 +05301642 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1643 {
1644 hdd_link_layer_process_radio_stats(pAdapter,
1645 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301646 spin_lock(&hdd_context_lock);
1647 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1648 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301649 }
1650 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1651 {
1652 hdd_link_layer_process_iface_stats(pAdapter,
1653 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301654 spin_lock(&hdd_context_lock);
1655 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1656 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301657 }
1658 else if ( linkLayerStatsResults->paramId &
1659 WMI_LINK_STATS_ALL_PEER )
1660 {
1661 hdd_link_layer_process_peer_stats(pAdapter,
1662 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301663 spin_lock(&hdd_context_lock);
1664 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1665 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301666 } /* WMI_LINK_STATS_ALL_PEER */
1667 else
1668 {
1669 hddLog(VOS_TRACE_LEVEL_ERROR,
1670 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1671 }
1672
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301673 spin_lock(&hdd_context_lock);
1674 /* complete response event if all requests are completed */
1675 if (0 == context->request_bitmap)
1676 complete(&context->response_event);
1677 spin_unlock(&hdd_context_lock);
1678
Sunil Duttc69bccb2014-05-26 21:30:20 +05301679 break;
1680 }
1681 default:
1682 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1683 break;
1684 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301685
1686 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301687 return;
1688}
1689
1690const struct
1691nla_policy
1692qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1693{
1694 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1695 { .type = NLA_U32 },
1696 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1697 { .type = NLA_U32 },
1698};
1699
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301700static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1701 struct wireless_dev *wdev,
1702 const void *data,
1703 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301704{
1705 int status;
1706 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301707 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301708 struct net_device *dev = wdev->netdev;
1709 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1710 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1711
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301712 ENTER();
1713
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714 status = wlan_hdd_validate_context(pHddCtx);
1715 if (0 != status)
1716 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301717 return -EINVAL;
1718 }
1719
1720 if (NULL == pAdapter)
1721 {
1722 hddLog(VOS_TRACE_LEVEL_ERROR,
1723 FL("HDD adapter is Null"));
1724 return -ENODEV;
1725 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301726 /* check the LLStats Capability */
1727 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1728 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1729 {
1730 hddLog(VOS_TRACE_LEVEL_ERROR,
1731 FL("Link Layer Statistics not supported by Firmware"));
1732 return -EINVAL;
1733 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301734
1735 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1736 (struct nlattr *)data,
1737 data_len, qca_wlan_vendor_ll_set_policy))
1738 {
1739 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1740 return -EINVAL;
1741 }
1742 if (!tb_vendor
1743 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1744 {
1745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1746 return -EINVAL;
1747 }
1748 if (!tb_vendor[
1749 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1750 {
1751 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1752 return -EINVAL;
1753 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301754 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301755 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301756
Dino Mycledf0a5d92014-07-04 09:41:55 +05301757 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301758 nla_get_u32(
1759 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1760
Dino Mycledf0a5d92014-07-04 09:41:55 +05301761 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301762 nla_get_u32(
1763 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1764
Dino Mycled3d50022014-07-07 12:58:25 +05301765 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1766 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301767
1768
1769 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301770 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1771 "Statistics Gathering = %d ",
1772 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1773 linkLayerStatsSetReq.mpduSizeThreshold,
1774 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301775
1776 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1777 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301778 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301779 {
1780 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1781 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301782 return -EINVAL;
1783
1784 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301785
Sunil Duttc69bccb2014-05-26 21:30:20 +05301786 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301787 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301788 {
1789 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1790 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301791 return -EINVAL;
1792 }
1793
1794 pAdapter->isLinkLayerStatsSet = 1;
1795
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301796 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301797 return 0;
1798}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301799static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1800 struct wireless_dev *wdev,
1801 const void *data,
1802 int data_len)
1803{
1804 int ret = 0;
1805
1806 vos_ssr_protect(__func__);
1807 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1808 vos_ssr_unprotect(__func__);
1809
1810 return ret;
1811}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301812
1813const struct
1814nla_policy
1815qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1816{
1817 /* Unsigned 32bit value provided by the caller issuing the GET stats
1818 * command. When reporting
1819 * the stats results, the driver uses the same value to indicate
1820 * which GET request the results
1821 * correspond to.
1822 */
1823 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1824
1825 /* Unsigned 32bit value . bit mask to identify what statistics are
1826 requested for retrieval */
1827 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1828};
1829
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301830static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1831 struct wireless_dev *wdev,
1832 const void *data,
1833 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301834{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301835 unsigned long rc;
1836 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301837 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1838 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301839 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301840 struct net_device *dev = wdev->netdev;
1841 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301842 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301843 int status;
1844
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301845 ENTER();
1846
Sunil Duttc69bccb2014-05-26 21:30:20 +05301847 status = wlan_hdd_validate_context(pHddCtx);
1848 if (0 != status)
1849 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301850 return -EINVAL ;
1851 }
1852
1853 if (NULL == pAdapter)
1854 {
1855 hddLog(VOS_TRACE_LEVEL_FATAL,
1856 "%s: HDD adapter is Null", __func__);
1857 return -ENODEV;
1858 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301859
1860 if (pHddStaCtx == NULL)
1861 {
1862 hddLog(VOS_TRACE_LEVEL_FATAL,
1863 "%s: HddStaCtx is Null", __func__);
1864 return -ENODEV;
1865 }
1866
Dino Mycledf0a5d92014-07-04 09:41:55 +05301867 /* check the LLStats Capability */
1868 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1869 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1870 {
1871 hddLog(VOS_TRACE_LEVEL_ERROR,
1872 FL("Link Layer Statistics not supported by Firmware"));
1873 return -EINVAL;
1874 }
1875
Sunil Duttc69bccb2014-05-26 21:30:20 +05301876
1877 if (!pAdapter->isLinkLayerStatsSet)
1878 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05301879 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301880 "%s: isLinkLayerStatsSet : %d",
1881 __func__, pAdapter->isLinkLayerStatsSet);
1882 return -EINVAL;
1883 }
1884
Mukul Sharma10313ba2015-07-29 19:14:39 +05301885 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1886 {
1887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1888 "%s: Roaming in progress, so unable to proceed this request", __func__);
1889 return -EBUSY;
1890 }
1891
Sunil Duttc69bccb2014-05-26 21:30:20 +05301892 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1893 (struct nlattr *)data,
1894 data_len, qca_wlan_vendor_ll_get_policy))
1895 {
1896 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1897 return -EINVAL;
1898 }
1899
1900 if (!tb_vendor
1901 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1902 {
1903 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1904 return -EINVAL;
1905 }
1906
1907 if (!tb_vendor
1908 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1909 {
1910 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1911 return -EINVAL;
1912 }
1913
Sunil Duttc69bccb2014-05-26 21:30:20 +05301914
Dino Mycledf0a5d92014-07-04 09:41:55 +05301915 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 nla_get_u32( tb_vendor[
1917 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301918 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919 nla_get_u32( tb_vendor[
1920 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1921
Dino Mycled3d50022014-07-07 12:58:25 +05301922 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1923 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301924
1925 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301926 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1927 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301928 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301929
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301930 spin_lock(&hdd_context_lock);
1931 context = &pHddCtx->ll_stats_context;
1932 context->request_id = linkLayerStatsGetReq.reqId;
1933 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1934 INIT_COMPLETION(context->response_event);
1935 spin_unlock(&hdd_context_lock);
1936
Sunil Duttc69bccb2014-05-26 21:30:20 +05301937 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301938 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301939 {
1940 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1941 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301942 return -EINVAL;
1943 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301944
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301945 rc = wait_for_completion_timeout(&context->response_event,
1946 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1947 if (!rc)
1948 {
1949 hddLog(LOGE,
1950 FL("Target response timed out request id %d request bitmap 0x%x"),
1951 context->request_id, context->request_bitmap);
1952 return -ETIMEDOUT;
1953 }
1954
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301955 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301956 return 0;
1957}
1958
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301959static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1960 struct wireless_dev *wdev,
1961 const void *data,
1962 int data_len)
1963{
1964 int ret = 0;
1965
1966 vos_ssr_protect(__func__);
1967 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1968 vos_ssr_unprotect(__func__);
1969
1970 return ret;
1971}
1972
Sunil Duttc69bccb2014-05-26 21:30:20 +05301973const struct
1974nla_policy
1975qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1976{
1977 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1978 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1979 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1980 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1981};
1982
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301983static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1984 struct wireless_dev *wdev,
1985 const void *data,
1986 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301987{
1988 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1989 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301990 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301991 struct net_device *dev = wdev->netdev;
1992 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1993 u32 statsClearReqMask;
1994 u8 stopReq;
1995 int status;
1996
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301997 ENTER();
1998
Sunil Duttc69bccb2014-05-26 21:30:20 +05301999 status = wlan_hdd_validate_context(pHddCtx);
2000 if (0 != status)
2001 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302002 return -EINVAL;
2003 }
2004
2005 if (NULL == pAdapter)
2006 {
2007 hddLog(VOS_TRACE_LEVEL_FATAL,
2008 "%s: HDD adapter is Null", __func__);
2009 return -ENODEV;
2010 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302011 /* check the LLStats Capability */
2012 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2013 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2014 {
2015 hddLog(VOS_TRACE_LEVEL_ERROR,
2016 FL("Enable LLStats Capability"));
2017 return -EINVAL;
2018 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302019
2020 if (!pAdapter->isLinkLayerStatsSet)
2021 {
2022 hddLog(VOS_TRACE_LEVEL_FATAL,
2023 "%s: isLinkLayerStatsSet : %d",
2024 __func__, pAdapter->isLinkLayerStatsSet);
2025 return -EINVAL;
2026 }
2027
2028 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2029 (struct nlattr *)data,
2030 data_len, qca_wlan_vendor_ll_clr_policy))
2031 {
2032 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2033 return -EINVAL;
2034 }
2035
2036 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2037
2038 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2039 {
2040 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2041 return -EINVAL;
2042
2043 }
2044
Sunil Duttc69bccb2014-05-26 21:30:20 +05302045
Dino Mycledf0a5d92014-07-04 09:41:55 +05302046 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302047 nla_get_u32(
2048 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2049
Dino Mycledf0a5d92014-07-04 09:41:55 +05302050 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302051 nla_get_u8(
2052 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2053
2054 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302055 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302056
Dino Mycled3d50022014-07-07 12:58:25 +05302057 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2058 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302059
2060 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302061 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2062 "statsClearReqMask = 0x%X, stopReq = %d",
2063 linkLayerStatsClearReq.reqId,
2064 linkLayerStatsClearReq.macAddr,
2065 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302066 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302067
2068 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302069 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302070 {
2071 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302072 hdd_station_ctx_t *pHddStaCtx;
2073
2074 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2075 if (VOS_STATUS_SUCCESS !=
2076 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2077 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2078 {
2079 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2080 "WLANTL_ClearInterfaceStats Failed", __func__);
2081 return -EINVAL;
2082 }
2083 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2084 (statsClearReqMask & WIFI_STATS_IFACE)) {
2085 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2086 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2087 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2088 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2089 }
2090
Sunil Duttc69bccb2014-05-26 21:30:20 +05302091 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2092 2 * sizeof(u32) +
2093 NLMSG_HDRLEN);
2094
2095 if (temp_skbuff != NULL)
2096 {
2097
2098 if (nla_put_u32(temp_skbuff,
2099 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2100 statsClearReqMask) ||
2101 nla_put_u32(temp_skbuff,
2102 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2103 stopReq))
2104 {
2105 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2106 kfree_skb(temp_skbuff);
2107 return -EINVAL;
2108 }
2109 /* If the ask is to stop the stats collection as part of clear
2110 * (stopReq = 1) , ensure that no further requests of get
2111 * go to the firmware by having isLinkLayerStatsSet set to 0.
2112 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302113 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302114 * case the firmware is just asked to clear the statistics.
2115 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302116 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302117 pAdapter->isLinkLayerStatsSet = 0;
2118 return cfg80211_vendor_cmd_reply(temp_skbuff);
2119 }
2120 return -ENOMEM;
2121 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302122
2123 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302124 return -EINVAL;
2125}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302126static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2127 struct wireless_dev *wdev,
2128 const void *data,
2129 int data_len)
2130{
2131 int ret = 0;
2132
2133 vos_ssr_protect(__func__);
2134 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2135 vos_ssr_unprotect(__func__);
2136
2137 return ret;
2138
2139
2140}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2142
Dino Mycle6fb96c12014-06-10 11:52:40 +05302143#ifdef WLAN_FEATURE_EXTSCAN
2144static const struct nla_policy
2145wlan_hdd_extscan_config_policy
2146 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2147{
2148 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2149 { .type = NLA_U32 },
2150 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2151 { .type = NLA_U32 },
2152 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2153 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2154 { .type = NLA_U32 },
2155 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2157
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2159 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2161 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2162 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302163 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2164 { .type = NLA_U32 },
2165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2166 { .type = NLA_U32 },
2167 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2168 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2170 { .type = NLA_U32 },
2171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2172 { .type = NLA_U32 },
2173 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2174 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2176 { .type = NLA_U8 },
2177 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302178 { .type = NLA_U8 },
2179 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2180 { .type = NLA_U8 },
2181 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2182 { .type = NLA_U8 },
2183
2184 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2185 { .type = NLA_U32 },
2186 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2187 { .type = NLA_UNSPEC },
2188 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2189 { .type = NLA_S32 },
2190 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2191 { .type = NLA_S32 },
2192 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2193 { .type = NLA_U32 },
2194 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2195 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302196 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2197 { .type = NLA_U32 },
2198 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2199 { .type = NLA_BINARY,
2200 .len = IEEE80211_MAX_SSID_LEN + 1 },
2201 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302202 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302203 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2204 { .type = NLA_U32 },
2205 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2206 { .type = NLA_U8 },
2207 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2208 { .type = NLA_S32 },
2209 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2210 { .type = NLA_S32 },
2211 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2212 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302213};
2214
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302215/**
2216 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2217 * @ctx: hdd global context
2218 * @data: capabilities data
2219 *
2220 * Return: none
2221 */
2222static void
2223wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302224{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302225 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302226 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302227 tSirEXTScanCapabilitiesEvent *data =
2228 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302229
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302230 ENTER();
2231
2232 if (wlan_hdd_validate_context(pHddCtx))
2233 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302234 return;
2235 }
2236
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302237 if (!pMsg)
2238 {
2239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2240 return;
2241 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302242
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302243 vos_spin_lock_acquire(&hdd_context_lock);
2244
2245 context = &pHddCtx->ext_scan_context;
2246 /* validate response received from target*/
2247 if (context->request_id != data->requestId)
2248 {
2249 vos_spin_lock_release(&hdd_context_lock);
2250 hddLog(LOGE,
2251 FL("Target response id did not match: request_id %d resposne_id %d"),
2252 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302253 return;
2254 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302255 else
2256 {
2257 context->capability_response = *data;
2258 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302259 }
2260
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302261 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302262
Dino Mycle6fb96c12014-06-10 11:52:40 +05302263 return;
2264}
2265
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302266/*
2267 * define short names for the global vendor params
2268 * used by wlan_hdd_send_ext_scan_capability()
2269 */
2270#define PARAM_REQUEST_ID \
2271 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2272#define PARAM_STATUS \
2273 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2274#define MAX_SCAN_CACHE_SIZE \
2275 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2276#define MAX_SCAN_BUCKETS \
2277 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2278#define MAX_AP_CACHE_PER_SCAN \
2279 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2280#define MAX_RSSI_SAMPLE_SIZE \
2281 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2282#define MAX_SCAN_RPT_THRHOLD \
2283 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2284#define MAX_HOTLIST_BSSIDS \
2285 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2286#define MAX_BSSID_HISTORY_ENTRIES \
2287 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2288#define MAX_HOTLIST_SSIDS \
2289 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302290#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2291 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302292
2293static int wlan_hdd_send_ext_scan_capability(void *ctx)
2294{
2295 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2296 struct sk_buff *skb = NULL;
2297 int ret;
2298 tSirEXTScanCapabilitiesEvent *data;
2299 tANI_U32 nl_buf_len;
2300
2301 ret = wlan_hdd_validate_context(pHddCtx);
2302 if (0 != ret)
2303 {
2304 return ret;
2305 }
2306
2307 data = &(pHddCtx->ext_scan_context.capability_response);
2308
2309 nl_buf_len = NLMSG_HDRLEN;
2310 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2311 (sizeof(data->status) + NLA_HDRLEN) +
2312 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2313 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2314 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2315 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2316 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2317 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2318 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2319 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2320
2321 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2322
2323 if (!skb)
2324 {
2325 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2326 return -ENOMEM;
2327 }
2328
2329 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2330 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2331 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2332 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2333 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2334 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2335 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2336 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2337
2338 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2339 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2340 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2341 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2342 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2343 data->maxApPerScan) ||
2344 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2345 data->maxRssiSampleSize) ||
2346 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2347 data->maxScanReportingThreshold) ||
2348 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2349 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2350 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302351 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2352 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302353 {
2354 hddLog(LOGE, FL("nla put fail"));
2355 goto nla_put_failure;
2356 }
2357
2358 cfg80211_vendor_cmd_reply(skb);
2359 return 0;
2360
2361nla_put_failure:
2362 kfree_skb(skb);
2363 return -EINVAL;;
2364}
2365
2366/*
2367 * done with short names for the global vendor params
2368 * used by wlan_hdd_send_ext_scan_capability()
2369 */
2370#undef PARAM_REQUEST_ID
2371#undef PARAM_STATUS
2372#undef MAX_SCAN_CACHE_SIZE
2373#undef MAX_SCAN_BUCKETS
2374#undef MAX_AP_CACHE_PER_SCAN
2375#undef MAX_RSSI_SAMPLE_SIZE
2376#undef MAX_SCAN_RPT_THRHOLD
2377#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302378#undef MAX_BSSID_HISTORY_ENTRIES
2379#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302380
2381static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2382{
2383 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2384 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302385 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302386 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302387
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302388 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302389
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302390 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302391 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302392
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302393 if (!pMsg)
2394 {
2395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302396 return;
2397 }
2398
Dino Mycle6fb96c12014-06-10 11:52:40 +05302399 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2400 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2401
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302402 context = &pHddCtx->ext_scan_context;
2403 spin_lock(&hdd_context_lock);
2404 if (context->request_id == pData->requestId) {
2405 context->response_status = pData->status ? -EINVAL : 0;
2406 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302407 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302408 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302409
2410 /*
2411 * Store the Request ID for comparing with the requestID obtained
2412 * in other requests.HDD shall return a failure is the extscan_stop
2413 * request is issued with a different requestId as that of the
2414 * extscan_start request. Also, This requestId shall be used while
2415 * indicating the full scan results to the upper layers.
2416 * The requestId is stored with the assumption that the firmware
2417 * shall return the ext scan start request's requestId in ext scan
2418 * start response.
2419 */
2420 if (pData->status == 0)
2421 pMac->sme.extScanStartReqId = pData->requestId;
2422
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302423 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302424 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302425}
2426
2427
2428static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2429{
2430 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2431 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302432 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302433
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302434 ENTER();
2435
2436 if (wlan_hdd_validate_context(pHddCtx)){
2437 return;
2438 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302439
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302440 if (!pMsg)
2441 {
2442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302443 return;
2444 }
2445
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302446 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2447 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302448
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302449 context = &pHddCtx->ext_scan_context;
2450 spin_lock(&hdd_context_lock);
2451 if (context->request_id == pData->requestId) {
2452 context->response_status = pData->status ? -EINVAL : 0;
2453 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302454 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302455 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302456
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302457 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302458 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302459}
2460
Dino Mycle6fb96c12014-06-10 11:52:40 +05302461static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2462 void *pMsg)
2463{
2464 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302465 tpSirEXTScanSetBssidHotListRspParams pData =
2466 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302467 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302468
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302469 ENTER();
2470
2471 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302472 return;
2473 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302474
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302475 if (!pMsg)
2476 {
2477 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2478 return;
2479 }
2480
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302481 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2482 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302483
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302484 context = &pHddCtx->ext_scan_context;
2485 spin_lock(&hdd_context_lock);
2486 if (context->request_id == pData->requestId) {
2487 context->response_status = pData->status ? -EINVAL : 0;
2488 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302489 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302490 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302491
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302492 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302493 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302494}
2495
2496static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2497 void *pMsg)
2498{
2499 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302500 tpSirEXTScanResetBssidHotlistRspParams pData =
2501 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302502 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302503
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302504 ENTER();
2505
2506 if (wlan_hdd_validate_context(pHddCtx)) {
2507 return;
2508 }
2509 if (!pMsg)
2510 {
2511 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302512 return;
2513 }
2514
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302515 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2516 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302517
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302518 context = &pHddCtx->ext_scan_context;
2519 spin_lock(&hdd_context_lock);
2520 if (context->request_id == pData->requestId) {
2521 context->response_status = pData->status ? -EINVAL : 0;
2522 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302523 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302524 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302525
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302526 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302527 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302528}
2529
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302530static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2531 void *pMsg)
2532{
2533 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2534 tpSirEXTScanSetSsidHotListRspParams pData =
2535 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2536 struct hdd_ext_scan_context *context;
2537
2538 if (wlan_hdd_validate_context(pHddCtx)){
2539 return;
2540 }
2541
2542 if (!pMsg)
2543 {
2544 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2545 return;
2546 }
2547
2548 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2549 pData->status);
2550
2551 context = &pHddCtx->ext_scan_context;
2552 spin_lock(&hdd_context_lock);
2553 if (context->request_id == pData->requestId) {
2554 context->response_status = pData->status ? -EINVAL : 0;
2555 complete(&context->response_event);
2556 }
2557 spin_unlock(&hdd_context_lock);
2558
2559 return;
2560}
2561
2562static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2563 void *pMsg)
2564{
2565 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2566 tpSirEXTScanResetSsidHotlistRspParams pData =
2567 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2568 struct hdd_ext_scan_context *context;
2569
2570 if (wlan_hdd_validate_context(pHddCtx)) {
2571 return;
2572 }
2573 if (!pMsg)
2574 {
2575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2576 return;
2577 }
2578
2579 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2580 pData->status);
2581
2582 context = &pHddCtx->ext_scan_context;
2583 spin_lock(&hdd_context_lock);
2584 if (context->request_id == pData->requestId) {
2585 context->response_status = pData->status ? -EINVAL : 0;
2586 complete(&context->response_event);
2587 }
2588 spin_unlock(&hdd_context_lock);
2589
2590 return;
2591}
2592
2593
Dino Mycle6fb96c12014-06-10 11:52:40 +05302594static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2595 void *pMsg)
2596{
2597 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2598 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302599 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302600 tANI_S32 totalResults;
2601 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302602 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2603 struct hdd_ext_scan_context *context;
2604 bool ignore_cached_results = false;
2605 tExtscanCachedScanResult *result;
2606 struct nlattr *nla_results;
2607 tANI_U16 ieLength= 0;
2608 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302609
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302610 ENTER();
2611
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302612 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302613 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302614
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302615 if (!pMsg)
2616 {
2617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2618 return;
2619 }
2620
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302621 spin_lock(&hdd_context_lock);
2622 context = &pHddCtx->ext_scan_context;
2623 ignore_cached_results = context->ignore_cached_results;
2624 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302626 if (ignore_cached_results) {
2627 hddLog(LOGE,
2628 FL("Ignore the cached results received after timeout"));
2629 return;
2630 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302631
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302632 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2633 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302634
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302635 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302636
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302637 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2638 scan_id_index++) {
2639 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302640
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302641 totalResults = result->num_results;
2642 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2643 result->scan_id, result->flags, totalResults);
2644 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302645
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302646 do{
2647 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2648 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2649 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302650
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302651 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2652 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2653
2654 if (!skb) {
2655 hddLog(VOS_TRACE_LEVEL_ERROR,
2656 FL("cfg80211_vendor_event_alloc failed"));
2657 return;
2658 }
2659
2660 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2661
2662 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2663 pData->requestId) ||
2664 nla_put_u32(skb,
2665 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2666 resultsPerEvent)) {
2667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2668 goto fail;
2669 }
2670 if (nla_put_u8(skb,
2671 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2672 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302673 {
2674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2675 goto fail;
2676 }
2677
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302678 if (nla_put_u32(skb,
2679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2680 result->scan_id)) {
2681 hddLog(LOGE, FL("put fail"));
2682 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302683 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302684
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302685 nla_results = nla_nest_start(skb,
2686 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2687 if (!nla_results)
2688 goto fail;
2689
2690 if (resultsPerEvent) {
2691 struct nlattr *aps;
2692 struct nlattr *nla_result;
2693
2694 nla_result = nla_nest_start(skb, scan_id_index);
2695 if(!nla_result)
2696 goto fail;
2697
2698 if (nla_put_u32(skb,
2699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2700 result->scan_id) ||
2701 nla_put_u32(skb,
2702 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2703 result->flags) ||
2704 nla_put_u32(skb,
2705 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2706 totalResults)) {
2707 hddLog(LOGE, FL("put fail"));
2708 goto fail;
2709 }
2710
2711 aps = nla_nest_start(skb,
2712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2713 if (!aps)
2714 {
2715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2716 goto fail;
2717 }
2718
2719 head_ptr = (tpSirWifiScanResult) &(result->ap);
2720
2721 for (j = 0; j < resultsPerEvent; j++, i++) {
2722 struct nlattr *ap;
2723 pSirWifiScanResult = head_ptr + i;
2724
2725 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05302726 * Firmware returns timestamp from extscan_start till
2727 * BSSID was cached (in micro seconds). Add this with
2728 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302729 * to derive the time since boot when the
2730 * BSSID was cached.
2731 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05302732 pSirWifiScanResult->ts +=
2733 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302734 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2735 "Ssid (%s)"
2736 "Bssid: %pM "
2737 "Channel (%u)"
2738 "Rssi (%d)"
2739 "RTT (%u)"
2740 "RTT_SD (%u)"
2741 "Beacon Period %u"
2742 "Capability 0x%x "
2743 "Ie length %d",
2744 i,
2745 pSirWifiScanResult->ts,
2746 pSirWifiScanResult->ssid,
2747 pSirWifiScanResult->bssid,
2748 pSirWifiScanResult->channel,
2749 pSirWifiScanResult->rssi,
2750 pSirWifiScanResult->rtt,
2751 pSirWifiScanResult->rtt_sd,
2752 pSirWifiScanResult->beaconPeriod,
2753 pSirWifiScanResult->capability,
2754 ieLength);
2755
2756 ap = nla_nest_start(skb, j + 1);
2757 if (!ap)
2758 {
2759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2760 goto fail;
2761 }
2762
2763 if (nla_put_u64(skb,
2764 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2765 pSirWifiScanResult->ts) )
2766 {
2767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2768 goto fail;
2769 }
2770 if (nla_put(skb,
2771 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2772 sizeof(pSirWifiScanResult->ssid),
2773 pSirWifiScanResult->ssid) )
2774 {
2775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2776 goto fail;
2777 }
2778 if (nla_put(skb,
2779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2780 sizeof(pSirWifiScanResult->bssid),
2781 pSirWifiScanResult->bssid) )
2782 {
2783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2784 goto fail;
2785 }
2786 if (nla_put_u32(skb,
2787 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2788 pSirWifiScanResult->channel) )
2789 {
2790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2791 goto fail;
2792 }
2793 if (nla_put_s32(skb,
2794 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2795 pSirWifiScanResult->rssi) )
2796 {
2797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2798 goto fail;
2799 }
2800 if (nla_put_u32(skb,
2801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2802 pSirWifiScanResult->rtt) )
2803 {
2804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2805 goto fail;
2806 }
2807 if (nla_put_u32(skb,
2808 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2809 pSirWifiScanResult->rtt_sd))
2810 {
2811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2812 goto fail;
2813 }
2814 if (nla_put_u32(skb,
2815 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2816 pSirWifiScanResult->beaconPeriod))
2817 {
2818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2819 goto fail;
2820 }
2821 if (nla_put_u32(skb,
2822 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2823 pSirWifiScanResult->capability))
2824 {
2825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2826 goto fail;
2827 }
2828 if (nla_put_u32(skb,
2829 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2830 ieLength))
2831 {
2832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2833 goto fail;
2834 }
2835
2836 if (ieLength)
2837 if (nla_put(skb,
2838 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2839 ieLength, ie)) {
2840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2841 goto fail;
2842 }
2843
2844 nla_nest_end(skb, ap);
2845 }
2846 nla_nest_end(skb, aps);
2847 nla_nest_end(skb, nla_result);
2848 }
2849
2850 nla_nest_end(skb, nla_results);
2851
2852 cfg80211_vendor_cmd_reply(skb);
2853
2854 } while (totalResults > 0);
2855 }
2856
2857 if (!pData->moreData) {
2858 spin_lock(&hdd_context_lock);
2859 context->response_status = 0;
2860 complete(&context->response_event);
2861 spin_unlock(&hdd_context_lock);
2862 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302863
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302864 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302865 return;
2866fail:
2867 kfree_skb(skb);
2868 return;
2869}
2870
2871static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2872 void *pMsg)
2873{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302874 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302875 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2876 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302877 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302878
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302879 ENTER();
2880
2881 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302882 hddLog(LOGE,
2883 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302884 return;
2885 }
2886 if (!pMsg)
2887 {
2888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302889 return;
2890 }
2891
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302892 if (pData->bss_found)
2893 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2894 else
2895 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2896
Dino Mycle6fb96c12014-06-10 11:52:40 +05302897 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302898#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2899 NULL,
2900#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302901 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302902 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302903
2904 if (!skb) {
2905 hddLog(VOS_TRACE_LEVEL_ERROR,
2906 FL("cfg80211_vendor_event_alloc failed"));
2907 return;
2908 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302909
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302910 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2911 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2912 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2913 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2914
2915 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302916 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2917 "Ssid (%s) "
2918 "Bssid (" MAC_ADDRESS_STR ") "
2919 "Channel (%u) "
2920 "Rssi (%d) "
2921 "RTT (%u) "
2922 "RTT_SD (%u) ",
2923 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302924 pData->bssHotlist[i].ts,
2925 pData->bssHotlist[i].ssid,
2926 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2927 pData->bssHotlist[i].channel,
2928 pData->bssHotlist[i].rssi,
2929 pData->bssHotlist[i].rtt,
2930 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302931 }
2932
2933 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2934 pData->requestId) ||
2935 nla_put_u32(skb,
2936 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302937 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2939 goto fail;
2940 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302941 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302942 struct nlattr *aps;
2943
2944 aps = nla_nest_start(skb,
2945 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2946 if (!aps)
2947 goto fail;
2948
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302949 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302950 struct nlattr *ap;
2951
2952 ap = nla_nest_start(skb, i + 1);
2953 if (!ap)
2954 goto fail;
2955
2956 if (nla_put_u64(skb,
2957 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302958 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302959 nla_put(skb,
2960 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302961 sizeof(pData->bssHotlist[i].ssid),
2962 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302963 nla_put(skb,
2964 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302965 sizeof(pData->bssHotlist[i].bssid),
2966 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302967 nla_put_u32(skb,
2968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302969 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302970 nla_put_s32(skb,
2971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302972 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302973 nla_put_u32(skb,
2974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302975 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302976 nla_put_u32(skb,
2977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302978 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302979 goto fail;
2980
2981 nla_nest_end(skb, ap);
2982 }
2983 nla_nest_end(skb, aps);
2984
2985 if (nla_put_u8(skb,
2986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2987 pData->moreData))
2988 goto fail;
2989 }
2990
2991 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302992 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302993 return;
2994
2995fail:
2996 kfree_skb(skb);
2997 return;
2998
2999}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303000
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303001/**
3002 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
3003 * Handle an SSID hotlist match event
3004 * @ctx: HDD context registered with SME
3005 * @event: The SSID hotlist match event
3006 *
3007 * This function will take an SSID match event that was generated by
3008 * firmware and will convert it into a cfg80211 vendor event which is
3009 * sent to userspace.
3010 *
3011 * Return: none
3012 */
3013static void
3014wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
3015 void *pMsg)
3016{
3017 hdd_context_t *hdd_ctx = ctx;
3018 struct sk_buff *skb;
3019 tANI_U32 i, index;
3020 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3021
3022 ENTER();
3023
3024 if (wlan_hdd_validate_context(hdd_ctx)) {
3025 hddLog(LOGE,
3026 FL("HDD context is not valid or response"));
3027 return;
3028 }
3029 if (!pMsg)
3030 {
3031 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3032 return;
3033 }
3034
3035 if (pData->ssid_found) {
3036 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3037 hddLog(LOG1, "SSID hotlist found");
3038 } else {
3039 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3040 hddLog(LOG1, "SSID hotlist lost");
3041 }
3042
3043 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3044#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3045 NULL,
3046#endif
3047 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3048 index, GFP_KERNEL);
3049
3050 if (!skb) {
3051 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3052 return;
3053 }
3054 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3055 pData->requestId, pData->numHotlistSsid, pData->moreData);
3056
3057 for (i = 0; i < pData->numHotlistSsid; i++) {
3058 hddLog(LOG1, "[i=%d] Timestamp %llu "
3059 "Ssid: %s "
3060 "Bssid (" MAC_ADDRESS_STR ") "
3061 "Channel %u "
3062 "Rssi %d "
3063 "RTT %u "
3064 "RTT_SD %u",
3065 i,
3066 pData->ssidHotlist[i].ts,
3067 pData->ssidHotlist[i].ssid,
3068 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3069 pData->ssidHotlist[i].channel,
3070 pData->ssidHotlist[i].rssi,
3071 pData->ssidHotlist[i].rtt,
3072 pData->ssidHotlist[i].rtt_sd);
3073 }
3074
3075 if (nla_put_u32(skb,
3076 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3077 pData->requestId) ||
3078 nla_put_u32(skb,
3079 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3080 pData->numHotlistSsid)) {
3081 hddLog(LOGE, FL("put fail"));
3082 goto fail;
3083 }
3084
3085 if (pData->numHotlistSsid) {
3086 struct nlattr *aps;
3087 aps = nla_nest_start(skb,
3088 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3089 if (!aps) {
3090 hddLog(LOGE, FL("nest fail"));
3091 goto fail;
3092 }
3093
3094 for (i = 0; i < pData->numHotlistSsid; i++) {
3095 struct nlattr *ap;
3096
3097 ap = nla_nest_start(skb, i);
3098 if (!ap) {
3099 hddLog(LOGE, FL("nest fail"));
3100 goto fail;
3101 }
3102
3103 if (nla_put_u64(skb,
3104 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3105 pData->ssidHotlist[i].ts) ||
3106 nla_put(skb,
3107 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3108 sizeof(pData->ssidHotlist[i].ssid),
3109 pData->ssidHotlist[i].ssid) ||
3110 nla_put(skb,
3111 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3112 sizeof(pData->ssidHotlist[i].bssid),
3113 pData->ssidHotlist[i].bssid) ||
3114 nla_put_u32(skb,
3115 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3116 pData->ssidHotlist[i].channel) ||
3117 nla_put_s32(skb,
3118 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3119 pData->ssidHotlist[i].rssi) ||
3120 nla_put_u32(skb,
3121 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3122 pData->ssidHotlist[i].rtt) ||
3123 nla_put_u32(skb,
3124 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3125 pData->ssidHotlist[i].rtt_sd)) {
3126 hddLog(LOGE, FL("put fail"));
3127 goto fail;
3128 }
3129 nla_nest_end(skb, ap);
3130 }
3131 nla_nest_end(skb, aps);
3132
3133 if (nla_put_u8(skb,
3134 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3135 pData->moreData)) {
3136 hddLog(LOGE, FL("put fail"));
3137 goto fail;
3138 }
3139 }
3140
3141 cfg80211_vendor_event(skb, GFP_KERNEL);
3142 return;
3143
3144fail:
3145 kfree_skb(skb);
3146 return;
3147
3148}
3149
3150
Dino Mycle6fb96c12014-06-10 11:52:40 +05303151static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3152 void *pMsg)
3153{
3154 struct sk_buff *skb;
3155 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3156 tpSirWifiFullScanResultEvent pData =
3157 (tpSirWifiFullScanResultEvent) (pMsg);
3158
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303159 ENTER();
3160
3161 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303162 hddLog(LOGE,
3163 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303164 return;
3165 }
3166 if (!pMsg)
3167 {
3168 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303169 return;
3170 }
3171
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303172 /*
3173 * If the full scan result including IE data exceeds NL 4K size
3174 * limitation, drop that beacon/probe rsp frame.
3175 */
3176 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3177 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3178 return;
3179 }
3180
Dino Mycle6fb96c12014-06-10 11:52:40 +05303181 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303182#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3183 NULL,
3184#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303185 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3186 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3187 GFP_KERNEL);
3188
3189 if (!skb) {
3190 hddLog(VOS_TRACE_LEVEL_ERROR,
3191 FL("cfg80211_vendor_event_alloc failed"));
3192 return;
3193 }
3194
Dino Mycle6fb96c12014-06-10 11:52:40 +05303195 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3196 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3197 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3198 "Ssid (%s)"
3199 "Bssid (" MAC_ADDRESS_STR ")"
3200 "Channel (%u)"
3201 "Rssi (%d)"
3202 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303203 "RTT_SD (%u)"
3204 "Bcn Period %d"
3205 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303206 pData->ap.ts,
3207 pData->ap.ssid,
3208 MAC_ADDR_ARRAY(pData->ap.bssid),
3209 pData->ap.channel,
3210 pData->ap.rssi,
3211 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303212 pData->ap.rtt_sd,
3213 pData->ap.beaconPeriod,
3214 pData->ap.capability);
3215
Dino Mycle6fb96c12014-06-10 11:52:40 +05303216 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3217 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3218 pData->requestId) ||
3219 nla_put_u64(skb,
3220 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3221 pData->ap.ts) ||
3222 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3223 sizeof(pData->ap.ssid),
3224 pData->ap.ssid) ||
3225 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3226 WNI_CFG_BSSID_LEN,
3227 pData->ap.bssid) ||
3228 nla_put_u32(skb,
3229 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3230 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303231 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303232 pData->ap.rssi) ||
3233 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3234 pData->ap.rtt) ||
3235 nla_put_u32(skb,
3236 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3237 pData->ap.rtt_sd) ||
3238 nla_put_u16(skb,
3239 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3240 pData->ap.beaconPeriod) ||
3241 nla_put_u16(skb,
3242 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3243 pData->ap.capability) ||
3244 nla_put_u32(skb,
3245 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303246 pData->ieLength) ||
3247 nla_put_u8(skb,
3248 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3249 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303250 {
3251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3252 goto nla_put_failure;
3253 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303254
3255 if (pData->ieLength) {
3256 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3257 pData->ieLength,
3258 pData->ie))
3259 {
3260 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3261 goto nla_put_failure;
3262 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303263 }
3264
3265 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303266 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303267 return;
3268
3269nla_put_failure:
3270 kfree_skb(skb);
3271 return;
3272}
3273
3274static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3275 void *pMsg)
3276{
3277 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3278 struct sk_buff *skb = NULL;
3279 tpSirEXTScanResultsAvailableIndParams pData =
3280 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3281
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303282 ENTER();
3283
3284 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303285 hddLog(LOGE,
3286 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303287 return;
3288 }
3289 if (!pMsg)
3290 {
3291 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303292 return;
3293 }
3294
3295 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303296#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3297 NULL,
3298#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303299 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3300 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3301 GFP_KERNEL);
3302
3303 if (!skb) {
3304 hddLog(VOS_TRACE_LEVEL_ERROR,
3305 FL("cfg80211_vendor_event_alloc failed"));
3306 return;
3307 }
3308
Dino Mycle6fb96c12014-06-10 11:52:40 +05303309 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3310 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3311 pData->numResultsAvailable);
3312 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3313 pData->requestId) ||
3314 nla_put_u32(skb,
3315 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3316 pData->numResultsAvailable)) {
3317 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3318 goto nla_put_failure;
3319 }
3320
3321 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303322 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303323 return;
3324
3325nla_put_failure:
3326 kfree_skb(skb);
3327 return;
3328}
3329
3330static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3331{
3332 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3333 struct sk_buff *skb = NULL;
3334 tpSirEXTScanProgressIndParams pData =
3335 (tpSirEXTScanProgressIndParams) pMsg;
3336
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303337 ENTER();
3338
3339 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303340 hddLog(LOGE,
3341 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303342 return;
3343 }
3344 if (!pMsg)
3345 {
3346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303347 return;
3348 }
3349
3350 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303351#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3352 NULL,
3353#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303354 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3355 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3356 GFP_KERNEL);
3357
3358 if (!skb) {
3359 hddLog(VOS_TRACE_LEVEL_ERROR,
3360 FL("cfg80211_vendor_event_alloc failed"));
3361 return;
3362 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303363 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303364 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3365 pData->extScanEventType);
3366 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3367 pData->status);
3368
3369 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3370 pData->extScanEventType) ||
3371 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303372 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3373 pData->requestId) ||
3374 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303375 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3376 pData->status)) {
3377 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3378 goto nla_put_failure;
3379 }
3380
3381 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303382 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303383 return;
3384
3385nla_put_failure:
3386 kfree_skb(skb);
3387 return;
3388}
3389
3390void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3391 void *pMsg)
3392{
3393 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3394
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303395 ENTER();
3396
Dino Mycle6fb96c12014-06-10 11:52:40 +05303397 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303398 return;
3399 }
3400
3401 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3402
3403
3404 switch(evType) {
3405 case SIR_HAL_EXTSCAN_START_RSP:
3406 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3407 break;
3408
3409 case SIR_HAL_EXTSCAN_STOP_RSP:
3410 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3411 break;
3412 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3413 /* There is no need to send this response to upper layer
3414 Just log the message */
3415 hddLog(VOS_TRACE_LEVEL_INFO,
3416 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3417 break;
3418 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3419 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3420 break;
3421
3422 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3423 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3424 break;
3425
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303426 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3427 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3428 break;
3429
3430 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3431 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3432 break;
3433
Dino Mycle6fb96c12014-06-10 11:52:40 +05303434 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303435 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303436 break;
3437 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3438 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3439 break;
3440 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3441 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3442 break;
3443 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3444 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3445 break;
3446 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3447 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3448 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303449 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3450 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3451 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303452 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3453 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3454 break;
3455 default:
3456 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3457 break;
3458 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303459 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460}
3461
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303462static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3463 struct wireless_dev *wdev,
3464 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303465{
Dino Myclee8843b32014-07-04 14:21:45 +05303466 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303467 struct net_device *dev = wdev->netdev;
3468 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3469 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3470 struct nlattr
3471 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3472 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303473 struct hdd_ext_scan_context *context;
3474 unsigned long rc;
3475 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303476
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303477 ENTER();
3478
Dino Mycle6fb96c12014-06-10 11:52:40 +05303479 status = wlan_hdd_validate_context(pHddCtx);
3480 if (0 != status)
3481 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303482 return -EINVAL;
3483 }
Dino Myclee8843b32014-07-04 14:21:45 +05303484 /* check the EXTScan Capability */
3485 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303486 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3487 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303488 {
3489 hddLog(VOS_TRACE_LEVEL_ERROR,
3490 FL("EXTScan not enabled/supported by Firmware"));
3491 return -EINVAL;
3492 }
3493
Dino Mycle6fb96c12014-06-10 11:52:40 +05303494 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3495 data, dataLen,
3496 wlan_hdd_extscan_config_policy)) {
3497 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3498 return -EINVAL;
3499 }
3500
3501 /* Parse and fetch request Id */
3502 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3503 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3504 return -EINVAL;
3505 }
3506
Dino Myclee8843b32014-07-04 14:21:45 +05303507 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303508 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303509 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303510
Dino Myclee8843b32014-07-04 14:21:45 +05303511 reqMsg.sessionId = pAdapter->sessionId;
3512 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303513
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303514 vos_spin_lock_acquire(&hdd_context_lock);
3515 context = &pHddCtx->ext_scan_context;
3516 context->request_id = reqMsg.requestId;
3517 INIT_COMPLETION(context->response_event);
3518 vos_spin_lock_release(&hdd_context_lock);
3519
Dino Myclee8843b32014-07-04 14:21:45 +05303520 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303521 if (!HAL_STATUS_SUCCESS(status)) {
3522 hddLog(VOS_TRACE_LEVEL_ERROR,
3523 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303524 return -EINVAL;
3525 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303526
3527 rc = wait_for_completion_timeout(&context->response_event,
3528 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3529 if (!rc) {
3530 hddLog(LOGE, FL("Target response timed out"));
3531 return -ETIMEDOUT;
3532 }
3533
3534 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3535 if (ret)
3536 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3537
3538 return ret;
3539
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303540 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303541 return 0;
3542}
3543
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303544static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3545 struct wireless_dev *wdev,
3546 const void *data, int dataLen)
3547{
3548 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303549
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303550 vos_ssr_protect(__func__);
3551 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3552 vos_ssr_unprotect(__func__);
3553
3554 return ret;
3555}
3556
3557static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3558 struct wireless_dev *wdev,
3559 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303560{
Dino Myclee8843b32014-07-04 14:21:45 +05303561 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303562 struct net_device *dev = wdev->netdev;
3563 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3564 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3565 struct nlattr
3566 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3567 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303568 struct hdd_ext_scan_context *context;
3569 unsigned long rc;
3570 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303571
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303572 ENTER();
3573
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303574 if (VOS_FTM_MODE == hdd_get_conparam()) {
3575 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3576 return -EINVAL;
3577 }
3578
Dino Mycle6fb96c12014-06-10 11:52:40 +05303579 status = wlan_hdd_validate_context(pHddCtx);
3580 if (0 != status)
3581 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303582 return -EINVAL;
3583 }
Dino Myclee8843b32014-07-04 14:21:45 +05303584 /* check the EXTScan Capability */
3585 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303586 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3587 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303588 {
3589 hddLog(VOS_TRACE_LEVEL_ERROR,
3590 FL("EXTScan not enabled/supported by Firmware"));
3591 return -EINVAL;
3592 }
3593
Dino Mycle6fb96c12014-06-10 11:52:40 +05303594 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3595 data, dataLen,
3596 wlan_hdd_extscan_config_policy)) {
3597 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3598 return -EINVAL;
3599 }
3600 /* Parse and fetch request Id */
3601 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3602 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3603 return -EINVAL;
3604 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303605
Dino Myclee8843b32014-07-04 14:21:45 +05303606 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303607 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3608
Dino Myclee8843b32014-07-04 14:21:45 +05303609 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303610
Dino Myclee8843b32014-07-04 14:21:45 +05303611 reqMsg.sessionId = pAdapter->sessionId;
3612 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303613
3614 /* Parse and fetch flush parameter */
3615 if (!tb
3616 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3617 {
3618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3619 goto failed;
3620 }
Dino Myclee8843b32014-07-04 14:21:45 +05303621 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303622 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3623
Dino Myclee8843b32014-07-04 14:21:45 +05303624 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303626 spin_lock(&hdd_context_lock);
3627 context = &pHddCtx->ext_scan_context;
3628 context->request_id = reqMsg.requestId;
3629 context->ignore_cached_results = false;
3630 INIT_COMPLETION(context->response_event);
3631 spin_unlock(&hdd_context_lock);
3632
Dino Myclee8843b32014-07-04 14:21:45 +05303633 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303634 if (!HAL_STATUS_SUCCESS(status)) {
3635 hddLog(VOS_TRACE_LEVEL_ERROR,
3636 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303637 return -EINVAL;
3638 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303639
3640 rc = wait_for_completion_timeout(&context->response_event,
3641 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3642 if (!rc) {
3643 hddLog(LOGE, FL("Target response timed out"));
3644 retval = -ETIMEDOUT;
3645 spin_lock(&hdd_context_lock);
3646 context->ignore_cached_results = true;
3647 spin_unlock(&hdd_context_lock);
3648 } else {
3649 spin_lock(&hdd_context_lock);
3650 retval = context->response_status;
3651 spin_unlock(&hdd_context_lock);
3652 }
3653
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303654 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303655 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303656
3657failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303658 return -EINVAL;
3659}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303660static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3661 struct wireless_dev *wdev,
3662 const void *data, int dataLen)
3663{
3664 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303665
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303666 vos_ssr_protect(__func__);
3667 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3668 vos_ssr_unprotect(__func__);
3669
3670 return ret;
3671}
3672
3673static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303674 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303675 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303676{
3677 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3678 struct net_device *dev = wdev->netdev;
3679 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3680 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3681 struct nlattr
3682 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3683 struct nlattr
3684 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3685 struct nlattr *apTh;
3686 eHalStatus status;
3687 tANI_U8 i = 0;
3688 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303689 struct hdd_ext_scan_context *context;
3690 tANI_U32 request_id;
3691 unsigned long rc;
3692 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303693
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303694 ENTER();
3695
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303696 if (VOS_FTM_MODE == hdd_get_conparam()) {
3697 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3698 return -EINVAL;
3699 }
3700
Dino Mycle6fb96c12014-06-10 11:52:40 +05303701 status = wlan_hdd_validate_context(pHddCtx);
3702 if (0 != status)
3703 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303704 return -EINVAL;
3705 }
Dino Myclee8843b32014-07-04 14:21:45 +05303706 /* check the EXTScan Capability */
3707 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303708 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3709 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303710 {
3711 hddLog(VOS_TRACE_LEVEL_ERROR,
3712 FL("EXTScan not enabled/supported by Firmware"));
3713 return -EINVAL;
3714 }
3715
Dino Mycle6fb96c12014-06-10 11:52:40 +05303716 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3717 data, dataLen,
3718 wlan_hdd_extscan_config_policy)) {
3719 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3720 return -EINVAL;
3721 }
3722
3723 /* Parse and fetch request Id */
3724 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3726 return -EINVAL;
3727 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303728 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3729 vos_mem_malloc(sizeof(*pReqMsg));
3730 if (!pReqMsg) {
3731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3732 return -ENOMEM;
3733 }
3734
Dino Myclee8843b32014-07-04 14:21:45 +05303735
Dino Mycle6fb96c12014-06-10 11:52:40 +05303736 pReqMsg->requestId = nla_get_u32(
3737 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3738 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3739
3740 /* Parse and fetch number of APs */
3741 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3742 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3743 goto fail;
3744 }
3745
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303746 /* Parse and fetch lost ap sample size */
3747 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3748 hddLog(LOGE, FL("attr lost ap sample size failed"));
3749 goto fail;
3750 }
3751
3752 pReqMsg->lostBssidSampleSize = nla_get_u32(
3753 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3754 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3755
Dino Mycle6fb96c12014-06-10 11:52:40 +05303756 pReqMsg->sessionId = pAdapter->sessionId;
3757 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3758
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303759 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303760 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303761 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303762
3763 nla_for_each_nested(apTh,
3764 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3765 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3766 nla_data(apTh), nla_len(apTh),
3767 NULL)) {
3768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3769 goto fail;
3770 }
3771
3772 /* Parse and fetch MAC address */
3773 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3775 goto fail;
3776 }
3777 memcpy(pReqMsg->ap[i].bssid, nla_data(
3778 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3779 sizeof(tSirMacAddr));
3780 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3781
3782 /* Parse and fetch low RSSI */
3783 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3785 goto fail;
3786 }
3787 pReqMsg->ap[i].low = nla_get_s32(
3788 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3789 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3790
3791 /* Parse and fetch high RSSI */
3792 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3794 goto fail;
3795 }
3796 pReqMsg->ap[i].high = nla_get_s32(
3797 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3798 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3799 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303800 i++;
3801 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303802
3803 context = &pHddCtx->ext_scan_context;
3804 spin_lock(&hdd_context_lock);
3805 INIT_COMPLETION(context->response_event);
3806 context->request_id = request_id = pReqMsg->requestId;
3807 spin_unlock(&hdd_context_lock);
3808
Dino Mycle6fb96c12014-06-10 11:52:40 +05303809 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3810 if (!HAL_STATUS_SUCCESS(status)) {
3811 hddLog(VOS_TRACE_LEVEL_ERROR,
3812 FL("sme_SetBssHotlist failed(err=%d)"), status);
3813 vos_mem_free(pReqMsg);
3814 return -EINVAL;
3815 }
3816
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303817 /* request was sent -- wait for the response */
3818 rc = wait_for_completion_timeout(&context->response_event,
3819 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3820
3821 if (!rc) {
3822 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3823 retval = -ETIMEDOUT;
3824 } else {
3825 spin_lock(&hdd_context_lock);
3826 if (context->request_id == request_id)
3827 retval = context->response_status;
3828 else
3829 retval = -EINVAL;
3830 spin_unlock(&hdd_context_lock);
3831 }
3832
Dino Myclee8843b32014-07-04 14:21:45 +05303833 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303834 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303835 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303836
3837fail:
3838 vos_mem_free(pReqMsg);
3839 return -EINVAL;
3840}
3841
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303842static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3843 struct wireless_dev *wdev,
3844 const void *data, int dataLen)
3845{
3846 int ret = 0;
3847
3848 vos_ssr_protect(__func__);
3849 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3850 dataLen);
3851 vos_ssr_unprotect(__func__);
3852
3853 return ret;
3854}
3855
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303856/*
3857 * define short names for the global vendor params
3858 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3859 */
3860#define PARAM_MAX \
3861QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3862#define PARAM_REQUEST_ID \
3863QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3864#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3865QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3866#define PARAMS_NUM_SSID \
3867QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3868#define THRESHOLD_PARAM \
3869QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3870#define PARAM_SSID \
3871QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3872#define PARAM_BAND \
3873QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3874#define PARAM_RSSI_LOW \
3875QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3876#define PARAM_RSSI_HIGH \
3877QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3878
3879/**
3880 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3881 * @wiphy: Pointer to wireless phy
3882 * @wdev: Pointer to wireless device
3883 * @data: Pointer to data
3884 * @data_len: Data length
3885 *
3886 * Return: 0 on success, negative errno on failure
3887 */
3888static int
3889__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3890 struct wireless_dev *wdev,
3891 const void *data,
3892 int data_len)
3893{
3894 tSirEXTScanSetSsidHotListReqParams *request;
3895 struct net_device *dev = wdev->netdev;
3896 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3897 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3898 struct nlattr *tb[PARAM_MAX + 1];
3899 struct nlattr *tb2[PARAM_MAX + 1];
3900 struct nlattr *ssids;
3901 struct hdd_ext_scan_context *context;
3902 uint32_t request_id;
3903 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3904 int ssid_len;
3905 eHalStatus status;
3906 int i, rem, retval;
3907 unsigned long rc;
3908
3909 ENTER();
3910
3911 if (VOS_FTM_MODE == hdd_get_conparam()) {
3912 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3913 return -EINVAL;
3914 }
3915
3916 retval = wlan_hdd_validate_context(hdd_ctx);
3917 if (0 != retval) {
3918 hddLog(LOGE, FL("HDD context is not valid"));
3919 return -EINVAL;
3920 }
3921
3922 /* check the EXTScan Capability */
3923 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303924 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3925 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303926 {
3927 hddLog(VOS_TRACE_LEVEL_ERROR,
3928 FL("EXTScan not enabled/supported by Firmware"));
3929 return -EINVAL;
3930 }
3931
3932 if (nla_parse(tb, PARAM_MAX,
3933 data, data_len,
3934 wlan_hdd_extscan_config_policy)) {
3935 hddLog(LOGE, FL("Invalid ATTR"));
3936 return -EINVAL;
3937 }
3938
3939 request = vos_mem_malloc(sizeof(*request));
3940 if (!request) {
3941 hddLog(LOGE, FL("vos_mem_malloc failed"));
3942 return -ENOMEM;
3943 }
3944
3945 /* Parse and fetch request Id */
3946 if (!tb[PARAM_REQUEST_ID]) {
3947 hddLog(LOGE, FL("attr request id failed"));
3948 goto fail;
3949 }
3950
3951 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3952 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3953
3954 /* Parse and fetch lost SSID sample size */
3955 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3956 hddLog(LOGE, FL("attr number of Ssid failed"));
3957 goto fail;
3958 }
3959 request->lost_ssid_sample_size =
3960 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3961 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3962 request->lost_ssid_sample_size);
3963
3964 /* Parse and fetch number of hotlist SSID */
3965 if (!tb[PARAMS_NUM_SSID]) {
3966 hddLog(LOGE, FL("attr number of Ssid failed"));
3967 goto fail;
3968 }
3969 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3970 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3971
3972 request->session_id = adapter->sessionId;
3973 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3974
3975 i = 0;
3976 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3977 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3978 hddLog(LOGE,
3979 FL("Too Many SSIDs, %d exceeds %d"),
3980 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3981 break;
3982 }
3983 if (nla_parse(tb2, PARAM_MAX,
3984 nla_data(ssids), nla_len(ssids),
3985 wlan_hdd_extscan_config_policy)) {
3986 hddLog(LOGE, FL("nla_parse failed"));
3987 goto fail;
3988 }
3989
3990 /* Parse and fetch SSID */
3991 if (!tb2[PARAM_SSID]) {
3992 hddLog(LOGE, FL("attr ssid failed"));
3993 goto fail;
3994 }
3995 nla_memcpy(ssid_string,
3996 tb2[PARAM_SSID],
3997 sizeof(ssid_string));
3998 hddLog(LOG1, FL("SSID %s"),
3999 ssid_string);
4000 ssid_len = strlen(ssid_string);
4001 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
4002 request->ssid[i].ssid.length = ssid_len;
4003 request->ssid[i].ssid.ssId[ssid_len] = '\0';
4004 hddLog(LOG1, FL("After copying SSID %s"),
4005 request->ssid[i].ssid.ssId);
4006 hddLog(LOG1, FL("After copying length: %d"),
4007 ssid_len);
4008
4009 /* Parse and fetch low RSSI */
4010 if (!tb2[PARAM_BAND]) {
4011 hddLog(LOGE, FL("attr band failed"));
4012 goto fail;
4013 }
4014 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
4015 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
4016
4017 /* Parse and fetch low RSSI */
4018 if (!tb2[PARAM_RSSI_LOW]) {
4019 hddLog(LOGE, FL("attr low RSSI failed"));
4020 goto fail;
4021 }
4022 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4023 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4024
4025 /* Parse and fetch high RSSI */
4026 if (!tb2[PARAM_RSSI_HIGH]) {
4027 hddLog(LOGE, FL("attr high RSSI failed"));
4028 goto fail;
4029 }
4030 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4031 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4032 i++;
4033 }
4034
4035 context = &hdd_ctx->ext_scan_context;
4036 spin_lock(&hdd_context_lock);
4037 INIT_COMPLETION(context->response_event);
4038 context->request_id = request_id = request->request_id;
4039 spin_unlock(&hdd_context_lock);
4040
4041 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4042 if (!HAL_STATUS_SUCCESS(status)) {
4043 hddLog(LOGE,
4044 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4045 goto fail;
4046 }
4047
4048 vos_mem_free(request);
4049
4050 /* request was sent -- wait for the response */
4051 rc = wait_for_completion_timeout(&context->response_event,
4052 msecs_to_jiffies
4053 (WLAN_WAIT_TIME_EXTSCAN));
4054 if (!rc) {
4055 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4056 retval = -ETIMEDOUT;
4057 } else {
4058 spin_lock(&hdd_context_lock);
4059 if (context->request_id == request_id)
4060 retval = context->response_status;
4061 else
4062 retval = -EINVAL;
4063 spin_unlock(&hdd_context_lock);
4064 }
4065
4066 return retval;
4067
4068fail:
4069 vos_mem_free(request);
4070 return -EINVAL;
4071}
4072
4073/*
4074 * done with short names for the global vendor params
4075 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4076 */
4077#undef PARAM_MAX
4078#undef PARAM_REQUEST_ID
4079#undef PARAMS_NUM_SSID
4080#undef THRESHOLD_PARAM
4081#undef PARAM_SSID
4082#undef PARAM_BAND
4083#undef PARAM_RSSI_LOW
4084#undef PARAM_RSSI_HIGH
4085
4086static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4087 struct wireless_dev *wdev,
4088 const void *data, int dataLen)
4089{
4090 int ret = 0;
4091
4092 vos_ssr_protect(__func__);
4093 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4094 dataLen);
4095 vos_ssr_unprotect(__func__);
4096
4097 return ret;
4098}
4099
4100static int
4101__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4102 struct wireless_dev *wdev,
4103 const void *data,
4104 int data_len)
4105{
4106 tSirEXTScanResetSsidHotlistReqParams request;
4107 struct net_device *dev = wdev->netdev;
4108 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4109 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4110 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4111 struct hdd_ext_scan_context *context;
4112 uint32_t request_id;
4113 eHalStatus status;
4114 int retval;
4115 unsigned long rc;
4116
4117 ENTER();
4118
4119 if (VOS_FTM_MODE == hdd_get_conparam()) {
4120 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4121 return -EINVAL;
4122 }
4123
4124 retval = wlan_hdd_validate_context(hdd_ctx);
4125 if (0 != retval) {
4126 hddLog(LOGE, FL("HDD context is not valid"));
4127 return -EINVAL;
4128 }
4129
4130 /* check the EXTScan Capability */
4131 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304132 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4133 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304134 {
4135 hddLog(LOGE,
4136 FL("EXTScan not enabled/supported by Firmware"));
4137 return -EINVAL;
4138 }
4139
4140 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4141 data, data_len,
4142 wlan_hdd_extscan_config_policy)) {
4143 hddLog(LOGE, FL("Invalid ATTR"));
4144 return -EINVAL;
4145 }
4146
4147 /* Parse and fetch request Id */
4148 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4149 hddLog(LOGE, FL("attr request id failed"));
4150 return -EINVAL;
4151 }
4152
4153 request.requestId = nla_get_u32(
4154 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4155 request.sessionId = adapter->sessionId;
4156 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4157 request.sessionId);
4158
4159 context = &hdd_ctx->ext_scan_context;
4160 spin_lock(&hdd_context_lock);
4161 INIT_COMPLETION(context->response_event);
4162 context->request_id = request_id = request.requestId;
4163 spin_unlock(&hdd_context_lock);
4164
4165 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4166 if (!HAL_STATUS_SUCCESS(status)) {
4167 hddLog(LOGE,
4168 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4169 return -EINVAL;
4170 }
4171
4172 /* request was sent -- wait for the response */
4173 rc = wait_for_completion_timeout(&context->response_event,
4174 msecs_to_jiffies
4175 (WLAN_WAIT_TIME_EXTSCAN));
4176 if (!rc) {
4177 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4178 retval = -ETIMEDOUT;
4179 } else {
4180 spin_lock(&hdd_context_lock);
4181 if (context->request_id == request_id)
4182 retval = context->response_status;
4183 else
4184 retval = -EINVAL;
4185 spin_unlock(&hdd_context_lock);
4186 }
4187
4188 return retval;
4189}
4190
4191static int
4192wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4193 struct wireless_dev *wdev,
4194 const void *data,
4195 int data_len)
4196{
4197 int ret;
4198
4199 vos_ssr_protect(__func__);
4200 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4201 data, data_len);
4202 vos_ssr_unprotect(__func__);
4203
4204 return ret;
4205}
4206
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304207static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304208 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304209 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304210{
4211 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4212 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4213 tANI_U8 numChannels = 0;
4214 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304215 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304216 tWifiBand wifiBand;
4217 eHalStatus status;
4218 struct sk_buff *replySkb;
4219 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304220 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304221
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304222 ENTER();
4223
Dino Mycle6fb96c12014-06-10 11:52:40 +05304224 status = wlan_hdd_validate_context(pHddCtx);
4225 if (0 != status)
4226 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304227 return -EINVAL;
4228 }
Dino Myclee8843b32014-07-04 14:21:45 +05304229
Dino Mycle6fb96c12014-06-10 11:52:40 +05304230 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4231 data, dataLen,
4232 wlan_hdd_extscan_config_policy)) {
4233 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4234 return -EINVAL;
4235 }
4236
4237 /* Parse and fetch request Id */
4238 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4240 return -EINVAL;
4241 }
4242 requestId = nla_get_u32(
4243 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4244 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4245
4246 /* Parse and fetch wifi band */
4247 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4248 {
4249 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4250 return -EINVAL;
4251 }
4252 wifiBand = nla_get_u32(
4253 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4254 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4255
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304256 /* Parse and fetch max channels */
4257 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4258 {
4259 hddLog(LOGE, FL("attr max channels failed"));
4260 return -EINVAL;
4261 }
4262 maxChannels = nla_get_u32(
4263 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4264 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4265
Dino Mycle6fb96c12014-06-10 11:52:40 +05304266 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4267 wifiBand, ChannelList,
4268 &numChannels);
4269 if (eHAL_STATUS_SUCCESS != status) {
4270 hddLog(VOS_TRACE_LEVEL_ERROR,
4271 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4272 return -EINVAL;
4273 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304274
4275 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304276 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304277
Dino Mycle6fb96c12014-06-10 11:52:40 +05304278 for (i = 0; i < numChannels; i++)
4279 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4280
4281 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4282 sizeof(u32) * numChannels +
4283 NLMSG_HDRLEN);
4284
4285 if (!replySkb) {
4286 hddLog(VOS_TRACE_LEVEL_ERROR,
4287 FL("valid channels: buffer alloc fail"));
4288 return -EINVAL;
4289 }
4290 if (nla_put_u32(replySkb,
4291 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4292 numChannels) ||
4293 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4294 sizeof(u32) * numChannels, ChannelList)) {
4295
4296 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4297 kfree_skb(replySkb);
4298 return -EINVAL;
4299 }
4300
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304301 ret = cfg80211_vendor_cmd_reply(replySkb);
4302
4303 EXIT();
4304 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304305}
4306
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304307static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4308 struct wireless_dev *wdev,
4309 const void *data, int dataLen)
4310{
4311 int ret = 0;
4312
4313 vos_ssr_protect(__func__);
4314 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4315 dataLen);
4316 vos_ssr_unprotect(__func__);
4317
4318 return ret;
4319}
4320
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304321static int hdd_extscan_start_fill_bucket_channel_spec(
4322 hdd_context_t *pHddCtx,
4323 tpSirEXTScanStartReqParams pReqMsg,
4324 struct nlattr **tb)
4325{
4326 struct nlattr *bucket[
4327 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4328 struct nlattr *channel[
4329 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4330 struct nlattr *buckets;
4331 struct nlattr *channels;
4332 int rem1, rem2;
4333 eHalStatus status;
4334 tANI_U8 bktIndex, j, numChannels;
4335 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4336 tANI_U32 passive_max_chn_time, active_max_chn_time;
4337
4338 bktIndex = 0;
4339
4340 nla_for_each_nested(buckets,
4341 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4342 if (nla_parse(bucket,
4343 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4344 nla_data(buckets), nla_len(buckets), NULL)) {
4345 hddLog(LOGE, FL("nla_parse failed"));
4346 return -EINVAL;
4347 }
4348
4349 /* Parse and fetch bucket spec */
4350 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4351 hddLog(LOGE, FL("attr bucket index failed"));
4352 return -EINVAL;
4353 }
4354 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4355 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4356 hddLog(LOG1, FL("Bucket spec Index %d"),
4357 pReqMsg->buckets[bktIndex].bucket);
4358
4359 /* Parse and fetch wifi band */
4360 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4361 hddLog(LOGE, FL("attr wifi band failed"));
4362 return -EINVAL;
4363 }
4364 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4365 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4366 hddLog(LOG1, FL("Wifi band %d"),
4367 pReqMsg->buckets[bktIndex].band);
4368
4369 /* Parse and fetch period */
4370 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4371 hddLog(LOGE, FL("attr period failed"));
4372 return -EINVAL;
4373 }
4374 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4375 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4376 hddLog(LOG1, FL("period %d"),
4377 pReqMsg->buckets[bktIndex].period);
4378
4379 /* Parse and fetch report events */
4380 if (!bucket[
4381 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4382 hddLog(LOGE, FL("attr report events failed"));
4383 return -EINVAL;
4384 }
4385 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4386 bucket[
4387 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4388 hddLog(LOG1, FL("report events %d"),
4389 pReqMsg->buckets[bktIndex].reportEvents);
4390
4391 /* Parse and fetch max period */
4392 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4393 hddLog(LOGE, FL("attr max period failed"));
4394 return -EINVAL;
4395 }
4396 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4397 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4398 hddLog(LOG1, FL("max period %u"),
4399 pReqMsg->buckets[bktIndex].max_period);
4400
4401 /* Parse and fetch exponent */
4402 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4403 hddLog(LOGE, FL("attr exponent failed"));
4404 return -EINVAL;
4405 }
4406 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4407 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4408 hddLog(LOG1, FL("exponent %u"),
4409 pReqMsg->buckets[bktIndex].exponent);
4410
4411 /* Parse and fetch step count */
4412 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4413 hddLog(LOGE, FL("attr step count failed"));
4414 return -EINVAL;
4415 }
4416 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4417 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4418 hddLog(LOG1, FL("Step count %u"),
4419 pReqMsg->buckets[bktIndex].step_count);
4420
4421 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4422 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4423
4424 /* Framework shall pass the channel list if the input WiFi band is
4425 * WIFI_BAND_UNSPECIFIED.
4426 * If the input WiFi band is specified (any value other than
4427 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4428 */
4429 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4430 numChannels = 0;
4431 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4432 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4433 pReqMsg->buckets[bktIndex].band,
4434 chanList, &numChannels);
4435 if (!HAL_STATUS_SUCCESS(status)) {
4436 hddLog(LOGE,
4437 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4438 status);
4439 return -EINVAL;
4440 }
4441
4442 pReqMsg->buckets[bktIndex].numChannels =
4443 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4444 hddLog(LOG1, FL("Num channels %d"),
4445 pReqMsg->buckets[bktIndex].numChannels);
4446
4447 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4448 j++) {
4449 pReqMsg->buckets[bktIndex].channels[j].channel =
4450 chanList[j];
4451 pReqMsg->buckets[bktIndex].channels[j].
4452 chnlClass = 0;
4453 if (CSR_IS_CHANNEL_DFS(
4454 vos_freq_to_chan(chanList[j]))) {
4455 pReqMsg->buckets[bktIndex].channels[j].
4456 passive = 1;
4457 pReqMsg->buckets[bktIndex].channels[j].
4458 dwellTimeMs = passive_max_chn_time;
4459 } else {
4460 pReqMsg->buckets[bktIndex].channels[j].
4461 passive = 0;
4462 pReqMsg->buckets[bktIndex].channels[j].
4463 dwellTimeMs = active_max_chn_time;
4464 }
4465
4466 hddLog(LOG1,
4467 "Channel %u Passive %u Dwell time %u ms",
4468 pReqMsg->buckets[bktIndex].channels[j].channel,
4469 pReqMsg->buckets[bktIndex].channels[j].passive,
4470 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4471 }
4472
4473 bktIndex++;
4474 continue;
4475 }
4476
4477 /* Parse and fetch number of channels */
4478 if (!bucket[
4479 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4480 hddLog(LOGE, FL("attr num channels failed"));
4481 return -EINVAL;
4482 }
4483
4484 pReqMsg->buckets[bktIndex].numChannels =
4485 nla_get_u32(bucket[
4486 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4487 hddLog(LOG1, FL("num channels %d"),
4488 pReqMsg->buckets[bktIndex].numChannels);
4489
4490 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4491 hddLog(LOGE, FL("attr channel spec failed"));
4492 return -EINVAL;
4493 }
4494
4495 j = 0;
4496 nla_for_each_nested(channels,
4497 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4498 if (nla_parse(channel,
4499 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4500 nla_data(channels), nla_len(channels),
4501 wlan_hdd_extscan_config_policy)) {
4502 hddLog(LOGE, FL("nla_parse failed"));
4503 return -EINVAL;
4504 }
4505
4506 /* Parse and fetch channel */
4507 if (!channel[
4508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4509 hddLog(LOGE, FL("attr channel failed"));
4510 return -EINVAL;
4511 }
4512 pReqMsg->buckets[bktIndex].channels[j].channel =
4513 nla_get_u32(channel[
4514 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4515 hddLog(LOG1, FL("channel %u"),
4516 pReqMsg->buckets[bktIndex].channels[j].channel);
4517
4518 /* Parse and fetch dwell time */
4519 if (!channel[
4520 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4521 hddLog(LOGE, FL("attr dwelltime failed"));
4522 return -EINVAL;
4523 }
4524 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4525 nla_get_u32(channel[
4526 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4527
4528 hddLog(LOG1, FL("Dwell time (%u ms)"),
4529 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4530
4531
4532 /* Parse and fetch channel spec passive */
4533 if (!channel[
4534 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4535 hddLog(LOGE,
4536 FL("attr channel spec passive failed"));
4537 return -EINVAL;
4538 }
4539 pReqMsg->buckets[bktIndex].channels[j].passive =
4540 nla_get_u8(channel[
4541 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4542 hddLog(LOG1, FL("Chnl spec passive %u"),
4543 pReqMsg->buckets[bktIndex].channels[j].passive);
4544
4545 j++;
4546 }
4547
4548 bktIndex++;
4549 }
4550
4551 return 0;
4552}
4553
4554
4555/*
4556 * define short names for the global vendor params
4557 * used by wlan_hdd_cfg80211_extscan_start()
4558 */
4559#define PARAM_MAX \
4560QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4561#define PARAM_REQUEST_ID \
4562QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4563#define PARAM_BASE_PERIOD \
4564QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4565#define PARAM_MAX_AP_PER_SCAN \
4566QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4567#define PARAM_RPT_THRHLD_PERCENT \
4568QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4569#define PARAM_RPT_THRHLD_NUM_SCANS \
4570QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4571#define PARAM_NUM_BUCKETS \
4572QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4573
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304574static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304575 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304576 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304577{
Dino Myclee8843b32014-07-04 14:21:45 +05304578 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304579 struct net_device *dev = wdev->netdev;
4580 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4581 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4582 struct nlattr *tb[PARAM_MAX + 1];
4583 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304584 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304585 tANI_U32 request_id;
4586 struct hdd_ext_scan_context *context;
4587 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304588
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304589 ENTER();
4590
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304591 if (VOS_FTM_MODE == hdd_get_conparam()) {
4592 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4593 return -EINVAL;
4594 }
4595
Dino Mycle6fb96c12014-06-10 11:52:40 +05304596 status = wlan_hdd_validate_context(pHddCtx);
4597 if (0 != status)
4598 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304599 return -EINVAL;
4600 }
Dino Myclee8843b32014-07-04 14:21:45 +05304601 /* check the EXTScan Capability */
4602 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304603 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4604 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304605 {
4606 hddLog(VOS_TRACE_LEVEL_ERROR,
4607 FL("EXTScan not enabled/supported by Firmware"));
4608 return -EINVAL;
4609 }
4610
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304611 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304612 data, dataLen,
4613 wlan_hdd_extscan_config_policy)) {
4614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4615 return -EINVAL;
4616 }
4617
4618 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304619 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304620 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4621 return -EINVAL;
4622 }
4623
Dino Myclee8843b32014-07-04 14:21:45 +05304624 pReqMsg = (tpSirEXTScanStartReqParams)
4625 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304626 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4628 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304629 }
4630
4631 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304632 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304633 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4634
4635 pReqMsg->sessionId = pAdapter->sessionId;
4636 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4637
4638 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304639 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304640 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4641 goto fail;
4642 }
4643 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304644 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304645 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4646 pReqMsg->basePeriod);
4647
4648 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304649 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304650 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4651 goto fail;
4652 }
4653 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304654 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304655 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4656 pReqMsg->maxAPperScan);
4657
4658 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304659 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304660 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4661 goto fail;
4662 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304663 pReqMsg->reportThresholdPercent = nla_get_u8(
4664 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304665 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304666 pReqMsg->reportThresholdPercent);
4667
4668 /* Parse and fetch report threshold num scans */
4669 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4670 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4671 goto fail;
4672 }
4673 pReqMsg->reportThresholdNumScans = nla_get_u8(
4674 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4675 hddLog(LOG1, FL("Report Threshold num scans %d"),
4676 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304677
4678 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304679 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4681 goto fail;
4682 }
4683 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304684 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304685 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4686 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4687 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4688 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4689 }
4690 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4691 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304692
Dino Mycle6fb96c12014-06-10 11:52:40 +05304693 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4695 goto fail;
4696 }
4697
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304698 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304699
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304700 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4701 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304702
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304703 context = &pHddCtx->ext_scan_context;
4704 spin_lock(&hdd_context_lock);
4705 INIT_COMPLETION(context->response_event);
4706 context->request_id = request_id = pReqMsg->requestId;
4707 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304708
Dino Mycle6fb96c12014-06-10 11:52:40 +05304709 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4710 if (!HAL_STATUS_SUCCESS(status)) {
4711 hddLog(VOS_TRACE_LEVEL_ERROR,
4712 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304713 goto fail;
4714 }
4715
Srinivas Dasari91727c12016-03-23 17:59:06 +05304716 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4717
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304718 /* request was sent -- wait for the response */
4719 rc = wait_for_completion_timeout(&context->response_event,
4720 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4721
4722 if (!rc) {
4723 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4724 retval = -ETIMEDOUT;
4725 } else {
4726 spin_lock(&hdd_context_lock);
4727 if (context->request_id == request_id)
4728 retval = context->response_status;
4729 else
4730 retval = -EINVAL;
4731 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304732 }
4733
Dino Myclee8843b32014-07-04 14:21:45 +05304734 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304735 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304736 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304737
4738fail:
4739 vos_mem_free(pReqMsg);
4740 return -EINVAL;
4741}
4742
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304743/*
4744 * done with short names for the global vendor params
4745 * used by wlan_hdd_cfg80211_extscan_start()
4746 */
4747#undef PARAM_MAX
4748#undef PARAM_REQUEST_ID
4749#undef PARAM_BASE_PERIOD
4750#undef PARAMS_MAX_AP_PER_SCAN
4751#undef PARAMS_RPT_THRHLD_PERCENT
4752#undef PARAMS_RPT_THRHLD_NUM_SCANS
4753#undef PARAMS_NUM_BUCKETS
4754
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304755static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4756 struct wireless_dev *wdev,
4757 const void *data, int dataLen)
4758{
4759 int ret = 0;
4760
4761 vos_ssr_protect(__func__);
4762 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4763 vos_ssr_unprotect(__func__);
4764
4765 return ret;
4766}
4767
4768static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304769 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304770 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304771{
Dino Myclee8843b32014-07-04 14:21:45 +05304772 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304773 struct net_device *dev = wdev->netdev;
4774 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4775 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4776 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4777 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304778 int retval;
4779 unsigned long rc;
4780 struct hdd_ext_scan_context *context;
4781 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304782
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304783 ENTER();
4784
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304785 if (VOS_FTM_MODE == hdd_get_conparam()) {
4786 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4787 return -EINVAL;
4788 }
4789
Dino Mycle6fb96c12014-06-10 11:52:40 +05304790 status = wlan_hdd_validate_context(pHddCtx);
4791 if (0 != status)
4792 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304793 return -EINVAL;
4794 }
Dino Myclee8843b32014-07-04 14:21:45 +05304795 /* check the EXTScan Capability */
4796 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304797 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4798 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304799 {
4800 hddLog(VOS_TRACE_LEVEL_ERROR,
4801 FL("EXTScan not enabled/supported by Firmware"));
4802 return -EINVAL;
4803 }
4804
Dino Mycle6fb96c12014-06-10 11:52:40 +05304805 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4806 data, dataLen,
4807 wlan_hdd_extscan_config_policy)) {
4808 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4809 return -EINVAL;
4810 }
4811
4812 /* Parse and fetch request Id */
4813 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4814 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4815 return -EINVAL;
4816 }
4817
Dino Myclee8843b32014-07-04 14:21:45 +05304818 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304819 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304820 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304821
Dino Myclee8843b32014-07-04 14:21:45 +05304822 reqMsg.sessionId = pAdapter->sessionId;
4823 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304824
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304825 context = &pHddCtx->ext_scan_context;
4826 spin_lock(&hdd_context_lock);
4827 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304828 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304829 spin_unlock(&hdd_context_lock);
4830
Dino Myclee8843b32014-07-04 14:21:45 +05304831 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304832 if (!HAL_STATUS_SUCCESS(status)) {
4833 hddLog(VOS_TRACE_LEVEL_ERROR,
4834 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304835 return -EINVAL;
4836 }
4837
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304838 /* request was sent -- wait for the response */
4839 rc = wait_for_completion_timeout(&context->response_event,
4840 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4841
4842 if (!rc) {
4843 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4844 retval = -ETIMEDOUT;
4845 } else {
4846 spin_lock(&hdd_context_lock);
4847 if (context->request_id == request_id)
4848 retval = context->response_status;
4849 else
4850 retval = -EINVAL;
4851 spin_unlock(&hdd_context_lock);
4852 }
4853
4854 return retval;
4855
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304856 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304857 return 0;
4858}
4859
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304860static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4861 struct wireless_dev *wdev,
4862 const void *data, int dataLen)
4863{
4864 int ret = 0;
4865
4866 vos_ssr_protect(__func__);
4867 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4868 vos_ssr_unprotect(__func__);
4869
4870 return ret;
4871}
4872
4873static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304874 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304875 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304876{
Dino Myclee8843b32014-07-04 14:21:45 +05304877 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304878 struct net_device *dev = wdev->netdev;
4879 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4880 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4881 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4882 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304883 struct hdd_ext_scan_context *context;
4884 tANI_U32 request_id;
4885 unsigned long rc;
4886 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304887
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304888 ENTER();
4889
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304890 if (VOS_FTM_MODE == hdd_get_conparam()) {
4891 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4892 return -EINVAL;
4893 }
4894
Dino Mycle6fb96c12014-06-10 11:52:40 +05304895 status = wlan_hdd_validate_context(pHddCtx);
4896 if (0 != status)
4897 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304898 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304899 return -EINVAL;
4900 }
Dino Myclee8843b32014-07-04 14:21:45 +05304901 /* check the EXTScan Capability */
4902 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304903 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4904 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304905 {
4906 hddLog(VOS_TRACE_LEVEL_ERROR,
4907 FL("EXTScan not enabled/supported by Firmware"));
4908 return -EINVAL;
4909 }
4910
Dino Mycle6fb96c12014-06-10 11:52:40 +05304911 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4912 data, dataLen,
4913 wlan_hdd_extscan_config_policy)) {
4914 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4915 return -EINVAL;
4916 }
4917
4918 /* Parse and fetch request Id */
4919 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4920 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4921 return -EINVAL;
4922 }
4923
Dino Myclee8843b32014-07-04 14:21:45 +05304924 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304925 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304926 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304927
Dino Myclee8843b32014-07-04 14:21:45 +05304928 reqMsg.sessionId = pAdapter->sessionId;
4929 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304930
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304931 context = &pHddCtx->ext_scan_context;
4932 spin_lock(&hdd_context_lock);
4933 INIT_COMPLETION(context->response_event);
4934 context->request_id = request_id = reqMsg.requestId;
4935 spin_unlock(&hdd_context_lock);
4936
Dino Myclee8843b32014-07-04 14:21:45 +05304937 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304938 if (!HAL_STATUS_SUCCESS(status)) {
4939 hddLog(VOS_TRACE_LEVEL_ERROR,
4940 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304941 return -EINVAL;
4942 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304943
4944 /* request was sent -- wait for the response */
4945 rc = wait_for_completion_timeout(&context->response_event,
4946 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4947 if (!rc) {
4948 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4949 retval = -ETIMEDOUT;
4950 } else {
4951 spin_lock(&hdd_context_lock);
4952 if (context->request_id == request_id)
4953 retval = context->response_status;
4954 else
4955 retval = -EINVAL;
4956 spin_unlock(&hdd_context_lock);
4957 }
4958
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304959 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304960 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304961}
4962
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304963static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4964 struct wireless_dev *wdev,
4965 const void *data, int dataLen)
4966{
4967 int ret = 0;
4968
4969 vos_ssr_protect(__func__);
4970 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4971 vos_ssr_unprotect(__func__);
4972
4973 return ret;
4974}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304975#endif /* WLAN_FEATURE_EXTSCAN */
4976
Atul Mittal115287b2014-07-08 13:26:33 +05304977/*EXT TDLS*/
4978static const struct nla_policy
4979wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4980{
4981 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4982 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4983 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4984 {.type = NLA_S32 },
4985 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4986 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4987
4988};
4989
4990static const struct nla_policy
4991wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4992{
4993 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4994
4995};
4996
4997static const struct nla_policy
4998wlan_hdd_tdls_config_state_change_policy[
4999 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5000{
5001 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
5002 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5003 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305004 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5005 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5006 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305007
5008};
5009
5010static const struct nla_policy
5011wlan_hdd_tdls_config_get_status_policy[
5012 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5013{
5014 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5015 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5016 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305017 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5018 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5019 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305020
5021};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305022
5023static const struct nla_policy
5024wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5025{
5026 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5027};
5028
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305029static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305030 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305031 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305032 int data_len)
5033{
5034
5035 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5036 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5037
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305038 ENTER();
5039
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305040 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305041 return -EINVAL;
5042 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305043 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305044 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305045 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305046 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305047 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305048 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305049 return -ENOTSUPP;
5050 }
5051
5052 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5053 data, data_len, wlan_hdd_mac_config)) {
5054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5055 return -EINVAL;
5056 }
5057
5058 /* Parse and fetch mac address */
5059 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5061 return -EINVAL;
5062 }
5063
5064 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5065 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5066 VOS_MAC_ADDR_LAST_3_BYTES);
5067
Siddharth Bhal76972212014-10-15 16:22:51 +05305068 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5069
5070 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305071 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5072 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305073 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5074 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5075 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5076 {
5077 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5078 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5079 VOS_MAC_ADDRESS_LEN);
5080 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305081 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305082
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305083 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5084 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305085
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305086 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305087 return 0;
5088}
5089
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305090static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5091 struct wireless_dev *wdev,
5092 const void *data,
5093 int data_len)
5094{
5095 int ret = 0;
5096
5097 vos_ssr_protect(__func__);
5098 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5099 vos_ssr_unprotect(__func__);
5100
5101 return ret;
5102}
5103
5104static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305105 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305106 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305107 int data_len)
5108{
5109 u8 peer[6] = {0};
5110 struct net_device *dev = wdev->netdev;
5111 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5112 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5113 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5114 eHalStatus ret;
5115 tANI_S32 state;
5116 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305117 tANI_S32 global_operating_class = 0;
5118 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305119 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305120 int retVal;
5121
5122 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305123
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305124 if (!pAdapter) {
5125 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5126 return -EINVAL;
5127 }
5128
Atul Mittal115287b2014-07-08 13:26:33 +05305129 ret = wlan_hdd_validate_context(pHddCtx);
5130 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305131 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305132 return -EINVAL;
5133 }
5134 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305135 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305136 return -ENOTSUPP;
5137 }
5138 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5139 data, data_len,
5140 wlan_hdd_tdls_config_get_status_policy)) {
5141 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5142 return -EINVAL;
5143 }
5144
5145 /* Parse and fetch mac address */
5146 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5147 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5148 return -EINVAL;
5149 }
5150
5151 memcpy(peer, nla_data(
5152 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5153 sizeof(peer));
5154 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5155
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305156 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305157
Atul Mittal115287b2014-07-08 13:26:33 +05305158 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305159 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305160 NLMSG_HDRLEN);
5161
5162 if (!skb) {
5163 hddLog(VOS_TRACE_LEVEL_ERROR,
5164 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5165 return -EINVAL;
5166 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305167 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05305168 reason,
5169 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305170 global_operating_class,
5171 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305172 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305173 if (nla_put_s32(skb,
5174 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5175 state) ||
5176 nla_put_s32(skb,
5177 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5178 reason) ||
5179 nla_put_s32(skb,
5180 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5181 global_operating_class) ||
5182 nla_put_s32(skb,
5183 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5184 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305185
5186 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5187 goto nla_put_failure;
5188 }
5189
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305190 retVal = cfg80211_vendor_cmd_reply(skb);
5191 EXIT();
5192 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305193
5194nla_put_failure:
5195 kfree_skb(skb);
5196 return -EINVAL;
5197}
5198
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305199static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5200 struct wireless_dev *wdev,
5201 const void *data,
5202 int data_len)
5203{
5204 int ret = 0;
5205
5206 vos_ssr_protect(__func__);
5207 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5208 vos_ssr_unprotect(__func__);
5209
5210 return ret;
5211}
5212
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305213static int wlan_hdd_cfg80211_exttdls_callback(
5214#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5215 const tANI_U8* mac,
5216#else
5217 tANI_U8* mac,
5218#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305219 tANI_S32 state,
5220 tANI_S32 reason,
5221 void *ctx)
5222{
5223 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305224 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305225 tANI_S32 global_operating_class = 0;
5226 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305227 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305228
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305229 ENTER();
5230
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305231 if (!pAdapter) {
5232 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5233 return -EINVAL;
5234 }
5235
5236 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305237 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305239 return -EINVAL;
5240 }
5241
5242 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305243 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305244 return -ENOTSUPP;
5245 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305246 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5247#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5248 NULL,
5249#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305250 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5251 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5252 GFP_KERNEL);
5253
5254 if (!skb) {
5255 hddLog(VOS_TRACE_LEVEL_ERROR,
5256 FL("cfg80211_vendor_event_alloc failed"));
5257 return -EINVAL;
5258 }
5259 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305260 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5261 reason,
5262 state,
5263 global_operating_class,
5264 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305265 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5266 MAC_ADDR_ARRAY(mac));
5267
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305268 if (nla_put(skb,
5269 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5270 VOS_MAC_ADDR_SIZE, mac) ||
5271 nla_put_s32(skb,
5272 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5273 state) ||
5274 nla_put_s32(skb,
5275 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5276 reason) ||
5277 nla_put_s32(skb,
5278 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5279 channel) ||
5280 nla_put_s32(skb,
5281 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5282 global_operating_class)
5283 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305284 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5285 goto nla_put_failure;
5286 }
5287
5288 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305289 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305290 return (0);
5291
5292nla_put_failure:
5293 kfree_skb(skb);
5294 return -EINVAL;
5295}
5296
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305297static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305298 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305299 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305300 int data_len)
5301{
5302 u8 peer[6] = {0};
5303 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305304 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5305 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5306 eHalStatus status;
5307 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305308 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305309 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305310
5311 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305312
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305313 if (!dev) {
5314 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5315 return -EINVAL;
5316 }
5317
5318 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5319 if (!pAdapter) {
5320 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5321 return -EINVAL;
5322 }
5323
Atul Mittal115287b2014-07-08 13:26:33 +05305324 status = wlan_hdd_validate_context(pHddCtx);
5325 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305326 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305327 return -EINVAL;
5328 }
5329 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305330 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305331 return -ENOTSUPP;
5332 }
5333 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5334 data, data_len,
5335 wlan_hdd_tdls_config_enable_policy)) {
5336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5337 return -EINVAL;
5338 }
5339
5340 /* Parse and fetch mac address */
5341 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5342 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5343 return -EINVAL;
5344 }
5345
5346 memcpy(peer, nla_data(
5347 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5348 sizeof(peer));
5349 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5350
5351 /* Parse and fetch channel */
5352 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5354 return -EINVAL;
5355 }
5356 pReqMsg.channel = nla_get_s32(
5357 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5358 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5359
5360 /* Parse and fetch global operating class */
5361 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5362 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5363 return -EINVAL;
5364 }
5365 pReqMsg.global_operating_class = nla_get_s32(
5366 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5367 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5368 pReqMsg.global_operating_class);
5369
5370 /* Parse and fetch latency ms */
5371 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5373 return -EINVAL;
5374 }
5375 pReqMsg.max_latency_ms = nla_get_s32(
5376 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5377 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5378 pReqMsg.max_latency_ms);
5379
5380 /* Parse and fetch required bandwidth kbps */
5381 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5382 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5383 return -EINVAL;
5384 }
5385
5386 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5387 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5388 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5389 pReqMsg.min_bandwidth_kbps);
5390
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305391 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305392 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305393 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305394 wlan_hdd_cfg80211_exttdls_callback);
5395
5396 EXIT();
5397 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305398}
5399
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305400static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5401 struct wireless_dev *wdev,
5402 const void *data,
5403 int data_len)
5404{
5405 int ret = 0;
5406
5407 vos_ssr_protect(__func__);
5408 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5409 vos_ssr_unprotect(__func__);
5410
5411 return ret;
5412}
5413
5414static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305415 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305416 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305417 int data_len)
5418{
5419 u8 peer[6] = {0};
5420 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305421 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5422 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5423 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305424 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305425 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305426
5427 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305428
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305429 if (!dev) {
5430 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5431 return -EINVAL;
5432 }
5433
5434 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5435 if (!pAdapter) {
5436 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5437 return -EINVAL;
5438 }
5439
Atul Mittal115287b2014-07-08 13:26:33 +05305440 status = wlan_hdd_validate_context(pHddCtx);
5441 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305443 return -EINVAL;
5444 }
5445 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305446 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305447 return -ENOTSUPP;
5448 }
5449 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5450 data, data_len,
5451 wlan_hdd_tdls_config_disable_policy)) {
5452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5453 return -EINVAL;
5454 }
5455 /* Parse and fetch mac address */
5456 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5458 return -EINVAL;
5459 }
5460
5461 memcpy(peer, nla_data(
5462 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5463 sizeof(peer));
5464 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5465
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305466 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5467
5468 EXIT();
5469 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305470}
5471
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305472static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5473 struct wireless_dev *wdev,
5474 const void *data,
5475 int data_len)
5476{
5477 int ret = 0;
5478
5479 vos_ssr_protect(__func__);
5480 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5481 vos_ssr_unprotect(__func__);
5482
5483 return ret;
5484}
5485
Dasari Srinivas7875a302014-09-26 17:50:57 +05305486static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305487__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305488 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305489 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305490{
5491 struct net_device *dev = wdev->netdev;
5492 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5493 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5494 struct sk_buff *skb = NULL;
5495 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305496 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305497
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305498 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305499
5500 ret = wlan_hdd_validate_context(pHddCtx);
5501 if (0 != ret)
5502 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305503 return ret;
5504 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305505 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5506 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5507 fset |= WIFI_FEATURE_INFRA;
5508 }
5509
5510 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5511 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5512 fset |= WIFI_FEATURE_INFRA_5G;
5513 }
5514
5515#ifdef WLAN_FEATURE_P2P
5516 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5517 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5518 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5519 fset |= WIFI_FEATURE_P2P;
5520 }
5521#endif
5522
5523 /* Soft-AP is supported currently by default */
5524 fset |= WIFI_FEATURE_SOFT_AP;
5525
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305526 /* HOTSPOT is a supplicant feature, enable it by default */
5527 fset |= WIFI_FEATURE_HOTSPOT;
5528
Dasari Srinivas7875a302014-09-26 17:50:57 +05305529#ifdef WLAN_FEATURE_EXTSCAN
5530 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305531 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5532 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5533 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305534 fset |= WIFI_FEATURE_EXTSCAN;
5535 }
5536#endif
5537
Dasari Srinivas7875a302014-09-26 17:50:57 +05305538 if (sme_IsFeatureSupportedByFW(NAN)) {
5539 hddLog(LOG1, FL("NAN is supported by firmware"));
5540 fset |= WIFI_FEATURE_NAN;
5541 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305542
5543 /* D2D RTT is not supported currently by default */
5544 if (sme_IsFeatureSupportedByFW(RTT)) {
5545 hddLog(LOG1, FL("RTT is supported by firmware"));
5546 fset |= WIFI_FEATURE_D2AP_RTT;
5547 }
5548
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305549 if (sme_IsFeatureSupportedByFW(RTT3)) {
5550 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5551 fset |= WIFI_FEATURE_RTT3;
5552 }
5553
Dasari Srinivas7875a302014-09-26 17:50:57 +05305554#ifdef FEATURE_WLAN_BATCH_SCAN
5555 if (fset & WIFI_FEATURE_EXTSCAN) {
5556 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5557 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5558 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5559 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5560 fset |= WIFI_FEATURE_BATCH_SCAN;
5561 }
5562#endif
5563
5564#ifdef FEATURE_WLAN_SCAN_PNO
5565 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5566 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5567 hddLog(LOG1, FL("PNO is supported by firmware"));
5568 fset |= WIFI_FEATURE_PNO;
5569 }
5570#endif
5571
5572 /* STA+STA is supported currently by default */
5573 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5574
5575#ifdef FEATURE_WLAN_TDLS
5576 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5577 sme_IsFeatureSupportedByFW(TDLS)) {
5578 hddLog(LOG1, FL("TDLS is supported by firmware"));
5579 fset |= WIFI_FEATURE_TDLS;
5580 }
5581
5582 /* TDLS_OFFCHANNEL is not supported currently by default */
5583#endif
5584
5585#ifdef WLAN_AP_STA_CONCURRENCY
5586 /* AP+STA concurrency is supported currently by default */
5587 fset |= WIFI_FEATURE_AP_STA;
5588#endif
5589
Mukul Sharma5add0532015-08-17 15:57:47 +05305590#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5591 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5592 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5593#endif
5594
Dasari Srinivas7875a302014-09-26 17:50:57 +05305595 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5596 NLMSG_HDRLEN);
5597
5598 if (!skb) {
5599 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5600 return -EINVAL;
5601 }
5602 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5603
5604 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5605 hddLog(LOGE, FL("nla put fail"));
5606 goto nla_put_failure;
5607 }
5608
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305609 ret = cfg80211_vendor_cmd_reply(skb);
5610 EXIT();
5611 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305612
5613nla_put_failure:
5614 kfree_skb(skb);
5615 return -EINVAL;
5616}
5617
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305618static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305619wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5620 struct wireless_dev *wdev,
5621 const void *data, int data_len)
5622{
5623 int ret = 0;
5624
5625 vos_ssr_protect(__func__);
5626 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5627 vos_ssr_unprotect(__func__);
5628
5629 return ret;
5630}
5631
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305632
5633static const struct
5634nla_policy
5635qca_wlan_vendor_wifi_logger_get_ring_data_policy
5636[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5637 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5638 = {.type = NLA_U32 },
5639};
5640
5641static int
5642 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5643 struct wireless_dev *wdev,
5644 const void *data,
5645 int data_len)
5646{
5647 int ret;
5648 VOS_STATUS status;
5649 uint32_t ring_id;
5650 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5651 struct nlattr *tb
5652 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5653
5654 ENTER();
5655
5656 ret = wlan_hdd_validate_context(hdd_ctx);
5657 if (0 != ret) {
5658 return ret;
5659 }
5660
5661 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5662 data, data_len,
5663 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5664 hddLog(LOGE, FL("Invalid attribute"));
5665 return -EINVAL;
5666 }
5667
5668 /* Parse and fetch ring id */
5669 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5670 hddLog(LOGE, FL("attr ATTR failed"));
5671 return -EINVAL;
5672 }
5673
5674 ring_id = nla_get_u32(
5675 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5676
5677 hddLog(LOG1, FL("Bug report triggered by framework"));
5678
5679 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5680 WLAN_LOG_INDICATOR_FRAMEWORK,
5681 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305682 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305683 );
5684 if (VOS_STATUS_SUCCESS != status) {
5685 hddLog(LOGE, FL("Failed to trigger bug report"));
5686
5687 return -EINVAL;
5688 }
5689
5690 return 0;
5691
5692
5693}
5694
5695
5696static int
5697 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5698 struct wireless_dev *wdev,
5699 const void *data,
5700 int data_len)
5701{
5702 int ret = 0;
5703
5704 vos_ssr_protect(__func__);
5705 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5706 wdev, data, data_len);
5707 vos_ssr_unprotect(__func__);
5708
5709 return ret;
5710
5711}
5712
5713
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305714static int
5715__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305716 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305717 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305718{
5719 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5720 uint8_t i, feature_sets, max_feature_sets;
5721 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5722 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305723 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5724 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305725
5726 ENTER();
5727
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305728 ret = wlan_hdd_validate_context(pHddCtx);
5729 if (0 != ret)
5730 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305731 return ret;
5732 }
5733
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305734 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5735 data, data_len, NULL)) {
5736 hddLog(LOGE, FL("Invalid ATTR"));
5737 return -EINVAL;
5738 }
5739
5740 /* Parse and fetch max feature set */
5741 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5742 hddLog(LOGE, FL("Attr max feature set size failed"));
5743 return -EINVAL;
5744 }
5745 max_feature_sets = nla_get_u32(
5746 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5747 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5748
5749 /* Fill feature combination matrix */
5750 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305751 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5752 WIFI_FEATURE_P2P;
5753
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305754 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5755 WIFI_FEATURE_SOFT_AP;
5756
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305757 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5758 WIFI_FEATURE_SOFT_AP;
5759
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305760 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5761 WIFI_FEATURE_SOFT_AP |
5762 WIFI_FEATURE_P2P;
5763
5764 /* Add more feature combinations here */
5765
5766 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5767 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5768 hddLog(LOG1, "Feature set matrix");
5769 for (i = 0; i < feature_sets; i++)
5770 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5771
5772 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5773 sizeof(u32) * feature_sets +
5774 NLMSG_HDRLEN);
5775
5776 if (reply_skb) {
5777 if (nla_put_u32(reply_skb,
5778 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5779 feature_sets) ||
5780 nla_put(reply_skb,
5781 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5782 sizeof(u32) * feature_sets, feature_set_matrix)) {
5783 hddLog(LOGE, FL("nla put fail"));
5784 kfree_skb(reply_skb);
5785 return -EINVAL;
5786 }
5787
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305788 ret = cfg80211_vendor_cmd_reply(reply_skb);
5789 EXIT();
5790 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305791 }
5792 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5793 return -ENOMEM;
5794
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305795}
5796
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305797static int
5798wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5799 struct wireless_dev *wdev,
5800 const void *data, int data_len)
5801{
5802 int ret = 0;
5803
5804 vos_ssr_protect(__func__);
5805 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5806 data_len);
5807 vos_ssr_unprotect(__func__);
5808
5809 return ret;
5810}
5811
c_manjeecfd1efb2015-09-25 19:32:34 +05305812
5813static int
5814__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5815 struct wireless_dev *wdev,
5816 const void *data, int data_len)
5817{
5818 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5819 int ret;
5820 ENTER();
5821
5822 ret = wlan_hdd_validate_context(pHddCtx);
5823 if (0 != ret)
5824 {
5825 return ret;
5826 }
5827
5828 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5829 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5830 {
5831 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5832 return -EINVAL;
5833 }
5834 /*call common API for FW mem dump req*/
5835 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5836
Abhishek Singhc783fa72015-12-09 18:07:34 +05305837 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305838 {
5839 /*indicate to userspace the status of fw mem dump */
5840 wlan_indicate_mem_dump_complete(true);
5841 }
5842 else
5843 {
5844 /*else send failure to userspace */
5845 wlan_indicate_mem_dump_complete(false);
5846 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305847 EXIT();
5848 return ret;
5849}
5850
5851/**
5852 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5853 * @wiphy: pointer to wireless wiphy structure.
5854 * @wdev: pointer to wireless_dev structure.
5855 * @data: Pointer to the NL data.
5856 * @data_len:Length of @data
5857 *
5858 * This is called when wlan driver needs to get the firmware memory dump
5859 * via vendor specific command.
5860 *
5861 * Return: 0 on success, error number otherwise.
5862 */
5863
5864static int
5865wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5866 struct wireless_dev *wdev,
5867 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305868{
5869 int ret = 0;
5870 vos_ssr_protect(__func__);
5871 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5872 data_len);
5873 vos_ssr_unprotect(__func__);
5874 return ret;
5875}
c_manjeecfd1efb2015-09-25 19:32:34 +05305876
Sushant Kaushik8e644982015-09-23 12:18:54 +05305877static const struct
5878nla_policy
5879qca_wlan_vendor_wifi_logger_start_policy
5880[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5881 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5882 = {.type = NLA_U32 },
5883 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5884 = {.type = NLA_U32 },
5885 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5886 = {.type = NLA_U32 },
5887};
5888
5889/**
5890 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5891 * or disable the collection of packet statistics from the firmware
5892 * @wiphy: WIPHY structure pointer
5893 * @wdev: Wireless device structure pointer
5894 * @data: Pointer to the data received
5895 * @data_len: Length of the data received
5896 *
5897 * This function is used to enable or disable the collection of packet
5898 * statistics from the firmware
5899 *
5900 * Return: 0 on success and errno on failure
5901 */
5902static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5903 struct wireless_dev *wdev,
5904 const void *data,
5905 int data_len)
5906{
5907 eHalStatus status;
5908 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5909 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5910 tAniWifiStartLog start_log;
5911
5912 status = wlan_hdd_validate_context(hdd_ctx);
5913 if (0 != status) {
5914 return -EINVAL;
5915 }
5916
5917 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5918 data, data_len,
5919 qca_wlan_vendor_wifi_logger_start_policy)) {
5920 hddLog(LOGE, FL("Invalid attribute"));
5921 return -EINVAL;
5922 }
5923
5924 /* Parse and fetch ring id */
5925 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5926 hddLog(LOGE, FL("attr ATTR failed"));
5927 return -EINVAL;
5928 }
5929 start_log.ringId = nla_get_u32(
5930 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5931 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5932
5933 /* Parse and fetch verbose level */
5934 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5935 hddLog(LOGE, FL("attr verbose_level failed"));
5936 return -EINVAL;
5937 }
5938 start_log.verboseLevel = nla_get_u32(
5939 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5940 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5941
5942 /* Parse and fetch flag */
5943 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5944 hddLog(LOGE, FL("attr flag failed"));
5945 return -EINVAL;
5946 }
5947 start_log.flag = nla_get_u32(
5948 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5949 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5950
5951 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305952 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5953 !vos_isPktStatsEnabled()))
5954
Sushant Kaushik8e644982015-09-23 12:18:54 +05305955 {
5956 hddLog(LOGE, FL("per pkt stats not enabled"));
5957 return -EINVAL;
5958 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305959
Sushant Kaushik33200572015-08-05 16:46:20 +05305960 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305961 return 0;
5962}
5963
5964/**
5965 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5966 * or disable the collection of packet statistics from the firmware
5967 * @wiphy: WIPHY structure pointer
5968 * @wdev: Wireless device structure pointer
5969 * @data: Pointer to the data received
5970 * @data_len: Length of the data received
5971 *
5972 * This function is used to enable or disable the collection of packet
5973 * statistics from the firmware
5974 *
5975 * Return: 0 on success and errno on failure
5976 */
5977static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5978 struct wireless_dev *wdev,
5979 const void *data,
5980 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05305981{
5982 int ret = 0;
5983
5984 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305985
5986 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
5987 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05305988 vos_ssr_unprotect(__func__);
5989
5990 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05305991}
5992
5993
Agarwal Ashish738843c2014-09-25 12:27:56 +05305994static const struct nla_policy
5995wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5996 +1] =
5997{
5998 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5999};
6000
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306001static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306002 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306003 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306004 int data_len)
6005{
6006 struct net_device *dev = wdev->netdev;
6007 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6008 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6009 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6010 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6011 eHalStatus status;
6012 u32 dfsFlag = 0;
6013
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306014 ENTER();
6015
Agarwal Ashish738843c2014-09-25 12:27:56 +05306016 status = wlan_hdd_validate_context(pHddCtx);
6017 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306018 return -EINVAL;
6019 }
6020 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6021 data, data_len,
6022 wlan_hdd_set_no_dfs_flag_config_policy)) {
6023 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6024 return -EINVAL;
6025 }
6026
6027 /* Parse and fetch required bandwidth kbps */
6028 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6029 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6030 return -EINVAL;
6031 }
6032
6033 dfsFlag = nla_get_u32(
6034 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6035 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6036 dfsFlag);
6037
6038 pHddCtx->disable_dfs_flag = dfsFlag;
6039
6040 sme_disable_dfs_channel(hHal, dfsFlag);
6041 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306042
6043 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306044 return 0;
6045}
Atul Mittal115287b2014-07-08 13:26:33 +05306046
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306047static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6048 struct wireless_dev *wdev,
6049 const void *data,
6050 int data_len)
6051{
6052 int ret = 0;
6053
6054 vos_ssr_protect(__func__);
6055 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6056 vos_ssr_unprotect(__func__);
6057
6058 return ret;
6059
6060}
6061
Mukul Sharma2a271632014-10-13 14:59:01 +05306062const struct
6063nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6064{
6065 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6066 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6067};
6068
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306069static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306070 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306071{
6072
6073 u8 bssid[6] = {0};
6074 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6075 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6076 eHalStatus status = eHAL_STATUS_SUCCESS;
6077 v_U32_t isFwrRoamEnabled = FALSE;
6078 int ret;
6079
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306080 ENTER();
6081
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306082 ret = wlan_hdd_validate_context(pHddCtx);
6083 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306084 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306085 }
6086
6087 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6088 data, data_len,
6089 qca_wlan_vendor_attr);
6090 if (ret){
6091 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6092 return -EINVAL;
6093 }
6094
6095 /* Parse and fetch Enable flag */
6096 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6097 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6098 return -EINVAL;
6099 }
6100
6101 isFwrRoamEnabled = nla_get_u32(
6102 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6103
6104 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6105
6106 /* Parse and fetch bssid */
6107 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6108 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6109 return -EINVAL;
6110 }
6111
6112 memcpy(bssid, nla_data(
6113 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6114 sizeof(bssid));
6115 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6116
6117 //Update roaming
6118 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306119 if (!HAL_STATUS_SUCCESS(status)) {
6120 hddLog(LOGE,
6121 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6122 return -EINVAL;
6123 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306124 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306125 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306126}
6127
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306128static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6129 struct wireless_dev *wdev, const void *data, int data_len)
6130{
6131 int ret = 0;
6132
6133 vos_ssr_protect(__func__);
6134 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6135 vos_ssr_unprotect(__func__);
6136
6137 return ret;
6138}
6139
Sushant Kaushik847890c2015-09-28 16:05:17 +05306140static const struct
6141nla_policy
6142qca_wlan_vendor_get_wifi_info_policy[
6143 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6144 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6145 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6146};
6147
6148
6149/**
6150 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6151 * @wiphy: pointer to wireless wiphy structure.
6152 * @wdev: pointer to wireless_dev structure.
6153 * @data: Pointer to the data to be passed via vendor interface
6154 * @data_len:Length of the data to be passed
6155 *
6156 * This is called when wlan driver needs to send wifi driver related info
6157 * (driver/fw version) to the user space application upon request.
6158 *
6159 * Return: Return the Success or Failure code.
6160 */
6161static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6162 struct wireless_dev *wdev,
6163 const void *data, int data_len)
6164{
6165 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6166 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6167 tSirVersionString version;
6168 uint32 version_len;
6169 uint8 attr;
6170 int status;
6171 struct sk_buff *reply_skb = NULL;
6172
6173 if (VOS_FTM_MODE == hdd_get_conparam()) {
6174 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6175 return -EINVAL;
6176 }
6177
6178 status = wlan_hdd_validate_context(hdd_ctx);
6179 if (0 != status) {
6180 hddLog(LOGE, FL("HDD context is not valid"));
6181 return -EINVAL;
6182 }
6183
6184 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6185 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6186 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6187 return -EINVAL;
6188 }
6189
6190 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6191 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6192 QWLAN_VERSIONSTR);
6193 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6194 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6195 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6196 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6197 hdd_ctx->fw_Version);
6198 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6199 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6200 } else {
6201 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6202 return -EINVAL;
6203 }
6204
6205 version_len = strlen(version);
6206 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6207 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6208 if (!reply_skb) {
6209 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6210 return -ENOMEM;
6211 }
6212
6213 if (nla_put(reply_skb, attr, version_len, version)) {
6214 hddLog(LOGE, FL("nla put fail"));
6215 kfree_skb(reply_skb);
6216 return -EINVAL;
6217 }
6218
6219 return cfg80211_vendor_cmd_reply(reply_skb);
6220}
6221
6222/**
6223 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6224 * @wiphy: pointer to wireless wiphy structure.
6225 * @wdev: pointer to wireless_dev structure.
6226 * @data: Pointer to the data to be passed via vendor interface
6227 * @data_len:Length of the data to be passed
6228 * @data_len: Length of the data received
6229 *
6230 * This function is used to enable or disable the collection of packet
6231 * statistics from the firmware
6232 *
6233 * Return: 0 on success and errno on failure
6234 */
6235
6236static int
6237wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6238 struct wireless_dev *wdev,
6239 const void *data, int data_len)
6240
6241
6242{
6243 int ret = 0;
6244
6245 vos_ssr_protect(__func__);
6246 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6247 wdev, data, data_len);
6248 vos_ssr_unprotect(__func__);
6249
6250 return ret;
6251}
6252
6253
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306254/*
6255 * define short names for the global vendor params
6256 * used by __wlan_hdd_cfg80211_monitor_rssi()
6257 */
6258#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6259#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6260#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6261#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6262#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6263
6264/**---------------------------------------------------------------------------
6265
6266 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6267 monitor start is completed successfully.
6268
6269 \return - None
6270
6271 --------------------------------------------------------------------------*/
6272void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6273{
6274 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6275
6276 if (NULL == pHddCtx)
6277 {
6278 hddLog(VOS_TRACE_LEVEL_ERROR,
6279 "%s: HDD context is NULL",__func__);
6280 return;
6281 }
6282
6283 if (VOS_STATUS_SUCCESS == status)
6284 {
6285 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6286 }
6287 else
6288 {
6289 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6290 }
6291
6292 return;
6293}
6294
6295/**---------------------------------------------------------------------------
6296
6297 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6298 stop is completed successfully.
6299
6300 \return - None
6301
6302 --------------------------------------------------------------------------*/
6303void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6304{
6305 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6306
6307 if (NULL == pHddCtx)
6308 {
6309 hddLog(VOS_TRACE_LEVEL_ERROR,
6310 "%s: HDD context is NULL",__func__);
6311 return;
6312 }
6313
6314 if (VOS_STATUS_SUCCESS == status)
6315 {
6316 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6317 }
6318 else
6319 {
6320 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6321 }
6322
6323 return;
6324}
6325
6326/**
6327 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6328 * @wiphy: Pointer to wireless phy
6329 * @wdev: Pointer to wireless device
6330 * @data: Pointer to data
6331 * @data_len: Data length
6332 *
6333 * Return: 0 on success, negative errno on failure
6334 */
6335
6336static int
6337__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6338 struct wireless_dev *wdev,
6339 const void *data,
6340 int data_len)
6341{
6342 struct net_device *dev = wdev->netdev;
6343 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6344 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6345 hdd_station_ctx_t *pHddStaCtx;
6346 struct nlattr *tb[PARAM_MAX + 1];
6347 tpSirRssiMonitorReq pReq;
6348 eHalStatus status;
6349 int ret;
6350 uint32_t control;
6351 static const struct nla_policy policy[PARAM_MAX + 1] = {
6352 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6353 [PARAM_CONTROL] = { .type = NLA_U32 },
6354 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6355 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6356 };
6357
6358 ENTER();
6359
6360 ret = wlan_hdd_validate_context(hdd_ctx);
6361 if (0 != ret) {
6362 return -EINVAL;
6363 }
6364
6365 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6366 hddLog(LOGE, FL("Not in Connected state!"));
6367 return -ENOTSUPP;
6368 }
6369
6370 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6371 hddLog(LOGE, FL("Invalid ATTR"));
6372 return -EINVAL;
6373 }
6374
6375 if (!tb[PARAM_REQUEST_ID]) {
6376 hddLog(LOGE, FL("attr request id failed"));
6377 return -EINVAL;
6378 }
6379
6380 if (!tb[PARAM_CONTROL]) {
6381 hddLog(LOGE, FL("attr control failed"));
6382 return -EINVAL;
6383 }
6384
6385 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6386
6387 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6388 if(NULL == pReq)
6389 {
6390 hddLog(LOGE,
6391 FL("vos_mem_alloc failed "));
6392 return eHAL_STATUS_FAILED_ALLOC;
6393 }
6394 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6395
6396 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6397 pReq->sessionId = pAdapter->sessionId;
6398 pReq->rssiMonitorCbContext = hdd_ctx;
6399 control = nla_get_u32(tb[PARAM_CONTROL]);
6400 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6401
6402 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6403 pReq->requestId, pReq->sessionId, control);
6404
6405 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6406 if (!tb[PARAM_MIN_RSSI]) {
6407 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306408 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306409 }
6410
6411 if (!tb[PARAM_MAX_RSSI]) {
6412 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306413 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306414 }
6415
6416 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6417 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6418 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6419
6420 if (!(pReq->minRssi < pReq->maxRssi)) {
6421 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6422 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306423 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306424 }
6425 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6426 pReq->minRssi, pReq->maxRssi);
6427 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6428
6429 }
6430 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6431 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6432 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6433 }
6434 else {
6435 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306436 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306437 }
6438
6439 if (!HAL_STATUS_SUCCESS(status)) {
6440 hddLog(LOGE,
6441 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306442 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306443 }
6444
6445 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306446fail:
6447 vos_mem_free(pReq);
6448 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306449}
6450
6451/*
6452 * done with short names for the global vendor params
6453 * used by __wlan_hdd_cfg80211_monitor_rssi()
6454 */
6455#undef PARAM_MAX
6456#undef PARAM_CONTROL
6457#undef PARAM_REQUEST_ID
6458#undef PARAM_MAX_RSSI
6459#undef PARAM_MIN_RSSI
6460
6461/**
6462 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6463 * @wiphy: wiphy structure pointer
6464 * @wdev: Wireless device structure pointer
6465 * @data: Pointer to the data received
6466 * @data_len: Length of @data
6467 *
6468 * Return: 0 on success; errno on failure
6469 */
6470static int
6471wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6472 const void *data, int data_len)
6473{
6474 int ret;
6475
6476 vos_ssr_protect(__func__);
6477 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6478 vos_ssr_unprotect(__func__);
6479
6480 return ret;
6481}
6482
6483/**
6484 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6485 * @hddctx: HDD context
6486 * @data: rssi breached event data
6487 *
6488 * This function reads the rssi breached event %data and fill in the skb with
6489 * NL attributes and send up the NL event.
6490 * This callback execute in atomic context and must not invoke any
6491 * blocking calls.
6492 *
6493 * Return: none
6494 */
6495void hdd_rssi_threshold_breached_cb(void *hddctx,
6496 struct rssi_breach_event *data)
6497{
6498 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6499 int status;
6500 struct sk_buff *skb;
6501
6502 ENTER();
6503 status = wlan_hdd_validate_context(pHddCtx);
6504
6505 if (0 != status) {
6506 return;
6507 }
6508
6509 if (!data) {
6510 hddLog(LOGE, FL("data is null"));
6511 return;
6512 }
6513
6514 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6515#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6516 NULL,
6517#endif
6518 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6519 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6520 GFP_KERNEL);
6521
6522 if (!skb) {
6523 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6524 return;
6525 }
6526
6527 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6528 data->request_id, data->curr_rssi);
6529 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6530 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6531
6532 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6533 data->request_id) ||
6534 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6535 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6536 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6537 data->curr_rssi)) {
6538 hddLog(LOGE, FL("nla put fail"));
6539 goto fail;
6540 }
6541
6542 cfg80211_vendor_event(skb, GFP_KERNEL);
6543 return;
6544
6545fail:
6546 kfree_skb(skb);
6547 return;
6548}
6549
6550
6551
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306552/**
6553 * __wlan_hdd_cfg80211_setband() - set band
6554 * @wiphy: Pointer to wireless phy
6555 * @wdev: Pointer to wireless device
6556 * @data: Pointer to data
6557 * @data_len: Data length
6558 *
6559 * Return: 0 on success, negative errno on failure
6560 */
6561static int
6562__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6563 struct wireless_dev *wdev,
6564 const void *data,
6565 int data_len)
6566{
6567 struct net_device *dev = wdev->netdev;
6568 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6569 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6570 int ret;
6571 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6572 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6573
6574 ENTER();
6575
6576 ret = wlan_hdd_validate_context(hdd_ctx);
6577 if (0 != ret) {
6578 hddLog(LOGE, FL("HDD context is not valid"));
6579 return ret;
6580 }
6581
6582 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6583 policy)) {
6584 hddLog(LOGE, FL("Invalid ATTR"));
6585 return -EINVAL;
6586 }
6587
6588 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6589 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6590 return -EINVAL;
6591 }
6592
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306593 hdd_ctx->isSetBandByNL = TRUE;
6594 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306595 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306596 hdd_ctx->isSetBandByNL = FALSE;
6597
6598 EXIT();
6599 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306600}
6601
6602/**
6603 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6604 * @wiphy: wiphy structure pointer
6605 * @wdev: Wireless device structure pointer
6606 * @data: Pointer to the data received
6607 * @data_len: Length of @data
6608 *
6609 * Return: 0 on success; errno on failure
6610 */
6611static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6612 struct wireless_dev *wdev,
6613 const void *data,
6614 int data_len)
6615{
6616 int ret = 0;
6617
6618 vos_ssr_protect(__func__);
6619 ret = __wlan_hdd_cfg80211_setband(wiphy,
6620 wdev, data, data_len);
6621 vos_ssr_unprotect(__func__);
6622
6623 return ret;
6624}
6625
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306626#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6627/**
6628 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6629 * @hdd_ctx: HDD context
6630 * @request_id: [input] request id
6631 * @pattern_id: [output] pattern id
6632 *
6633 * This function loops through request id to pattern id array
6634 * if the slot is available, store the request id and return pattern id
6635 * if entry exists, return the pattern id
6636 *
6637 * Return: 0 on success and errno on failure
6638 */
6639static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6640 uint32_t request_id,
6641 uint8_t *pattern_id)
6642{
6643 uint32_t i;
6644
6645 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6646 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6647 {
6648 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6649 {
6650 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6651 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6652 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6653 return 0;
6654 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6655 request_id) {
6656 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6657 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6658 return 0;
6659 }
6660 }
6661 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6662 return -EINVAL;
6663}
6664
6665/**
6666 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6667 * @hdd_ctx: HDD context
6668 * @request_id: [input] request id
6669 * @pattern_id: [output] pattern id
6670 *
6671 * This function loops through request id to pattern id array
6672 * reset request id to 0 (slot available again) and
6673 * return pattern id
6674 *
6675 * Return: 0 on success and errno on failure
6676 */
6677static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6678 uint32_t request_id,
6679 uint8_t *pattern_id)
6680{
6681 uint32_t i;
6682
6683 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6684 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6685 {
6686 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6687 {
6688 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6689 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6690 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6691 return 0;
6692 }
6693 }
6694 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6695 return -EINVAL;
6696}
6697
6698
6699/*
6700 * define short names for the global vendor params
6701 * used by __wlan_hdd_cfg80211_offloaded_packets()
6702 */
6703#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6704#define PARAM_REQUEST_ID \
6705 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6706#define PARAM_CONTROL \
6707 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6708#define PARAM_IP_PACKET \
6709 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6710#define PARAM_SRC_MAC_ADDR \
6711 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6712#define PARAM_DST_MAC_ADDR \
6713 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6714#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6715
6716/**
6717 * wlan_hdd_add_tx_ptrn() - add tx pattern
6718 * @adapter: adapter pointer
6719 * @hdd_ctx: hdd context
6720 * @tb: nl attributes
6721 *
6722 * This function reads the NL attributes and forms a AddTxPtrn message
6723 * posts it to SME.
6724 *
6725 */
6726static int
6727wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6728 struct nlattr **tb)
6729{
6730 struct sSirAddPeriodicTxPtrn *add_req;
6731 eHalStatus status;
6732 uint32_t request_id, ret, len;
6733 uint8_t pattern_id = 0;
6734 v_MACADDR_t dst_addr;
6735 uint16_t eth_type = htons(ETH_P_IP);
6736
6737 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6738 {
6739 hddLog(LOGE, FL("Not in Connected state!"));
6740 return -ENOTSUPP;
6741 }
6742
6743 add_req = vos_mem_malloc(sizeof(*add_req));
6744 if (!add_req)
6745 {
6746 hddLog(LOGE, FL("memory allocation failed"));
6747 return -ENOMEM;
6748 }
6749
6750 /* Parse and fetch request Id */
6751 if (!tb[PARAM_REQUEST_ID])
6752 {
6753 hddLog(LOGE, FL("attr request id failed"));
6754 goto fail;
6755 }
6756
6757 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6758 hddLog(LOG1, FL("Request Id: %u"), request_id);
6759 if (request_id == 0)
6760 {
6761 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306762 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306763 }
6764
6765 if (!tb[PARAM_PERIOD])
6766 {
6767 hddLog(LOGE, FL("attr period failed"));
6768 goto fail;
6769 }
6770 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6771 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6772 if (add_req->usPtrnIntervalMs == 0)
6773 {
6774 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6775 goto fail;
6776 }
6777
6778 if (!tb[PARAM_SRC_MAC_ADDR])
6779 {
6780 hddLog(LOGE, FL("attr source mac address failed"));
6781 goto fail;
6782 }
6783 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6784 VOS_MAC_ADDR_SIZE);
6785 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6786 MAC_ADDR_ARRAY(add_req->macAddress));
6787
6788 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6789 VOS_MAC_ADDR_SIZE))
6790 {
6791 hddLog(LOGE,
6792 FL("input src mac address and connected ap bssid are different"));
6793 goto fail;
6794 }
6795
6796 if (!tb[PARAM_DST_MAC_ADDR])
6797 {
6798 hddLog(LOGE, FL("attr dst mac address failed"));
6799 goto fail;
6800 }
6801 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6802 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6803 MAC_ADDR_ARRAY(dst_addr.bytes));
6804
6805 if (!tb[PARAM_IP_PACKET])
6806 {
6807 hddLog(LOGE, FL("attr ip packet failed"));
6808 goto fail;
6809 }
6810 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6811 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6812
6813 if (add_req->ucPtrnSize < 0 ||
6814 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6815 HDD_ETH_HEADER_LEN))
6816 {
6817 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6818 add_req->ucPtrnSize);
6819 goto fail;
6820 }
6821
6822 len = 0;
6823 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6824 len += VOS_MAC_ADDR_SIZE;
6825 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6826 VOS_MAC_ADDR_SIZE);
6827 len += VOS_MAC_ADDR_SIZE;
6828 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6829 len += 2;
6830
6831 /*
6832 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6833 * ------------------------------------------------------------
6834 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6835 * ------------------------------------------------------------
6836 */
6837 vos_mem_copy(&add_req->ucPattern[len],
6838 nla_data(tb[PARAM_IP_PACKET]),
6839 add_req->ucPtrnSize);
6840 add_req->ucPtrnSize += len;
6841
6842 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6843 add_req->ucPattern, add_req->ucPtrnSize);
6844
6845 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6846 if (ret)
6847 {
6848 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6849 goto fail;
6850 }
6851 add_req->ucPtrnId = pattern_id;
6852 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6853
6854 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6855 if (!HAL_STATUS_SUCCESS(status))
6856 {
6857 hddLog(LOGE,
6858 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6859 goto fail;
6860 }
6861
6862 EXIT();
6863 vos_mem_free(add_req);
6864 return 0;
6865
6866fail:
6867 vos_mem_free(add_req);
6868 return -EINVAL;
6869}
6870
6871/**
6872 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6873 * @adapter: adapter pointer
6874 * @hdd_ctx: hdd context
6875 * @tb: nl attributes
6876 *
6877 * This function reads the NL attributes and forms a DelTxPtrn message
6878 * posts it to SME.
6879 *
6880 */
6881static int
6882wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6883 struct nlattr **tb)
6884{
6885 struct sSirDelPeriodicTxPtrn *del_req;
6886 eHalStatus status;
6887 uint32_t request_id, ret;
6888 uint8_t pattern_id = 0;
6889
6890 /* Parse and fetch request Id */
6891 if (!tb[PARAM_REQUEST_ID])
6892 {
6893 hddLog(LOGE, FL("attr request id failed"));
6894 return -EINVAL;
6895 }
6896 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6897 if (request_id == 0)
6898 {
6899 hddLog(LOGE, FL("request_id cannot be zero"));
6900 return -EINVAL;
6901 }
6902
6903 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6904 if (ret)
6905 {
6906 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6907 return -EINVAL;
6908 }
6909
6910 del_req = vos_mem_malloc(sizeof(*del_req));
6911 if (!del_req)
6912 {
6913 hddLog(LOGE, FL("memory allocation failed"));
6914 return -ENOMEM;
6915 }
6916
6917 vos_mem_set(del_req, sizeof(*del_req), 0);
6918 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6919 VOS_MAC_ADDR_SIZE);
6920 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6921 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6922 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6923 request_id, pattern_id, del_req->ucPatternIdBitmap);
6924
6925 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6926 if (!HAL_STATUS_SUCCESS(status))
6927 {
6928 hddLog(LOGE,
6929 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6930 goto fail;
6931 }
6932
6933 EXIT();
6934 vos_mem_free(del_req);
6935 return 0;
6936
6937fail:
6938 vos_mem_free(del_req);
6939 return -EINVAL;
6940}
6941
6942
6943/**
6944 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6945 * @wiphy: Pointer to wireless phy
6946 * @wdev: Pointer to wireless device
6947 * @data: Pointer to data
6948 * @data_len: Data length
6949 *
6950 * Return: 0 on success, negative errno on failure
6951 */
6952static int
6953__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6954 struct wireless_dev *wdev,
6955 const void *data,
6956 int data_len)
6957{
6958 struct net_device *dev = wdev->netdev;
6959 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6960 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6961 struct nlattr *tb[PARAM_MAX + 1];
6962 uint8_t control;
6963 int ret;
6964 static const struct nla_policy policy[PARAM_MAX + 1] =
6965 {
6966 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6967 [PARAM_CONTROL] = { .type = NLA_U32 },
6968 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
6969 .len = VOS_MAC_ADDR_SIZE },
6970 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
6971 .len = VOS_MAC_ADDR_SIZE },
6972 [PARAM_PERIOD] = { .type = NLA_U32 },
6973 };
6974
6975 ENTER();
6976
6977 ret = wlan_hdd_validate_context(hdd_ctx);
6978 if (0 != ret)
6979 {
6980 hddLog(LOGE, FL("HDD context is not valid"));
6981 return ret;
6982 }
6983
6984 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
6985 {
6986 hddLog(LOGE,
6987 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
6988 return -ENOTSUPP;
6989 }
6990
6991 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
6992 {
6993 hddLog(LOGE, FL("Invalid ATTR"));
6994 return -EINVAL;
6995 }
6996
6997 if (!tb[PARAM_CONTROL])
6998 {
6999 hddLog(LOGE, FL("attr control failed"));
7000 return -EINVAL;
7001 }
7002 control = nla_get_u32(tb[PARAM_CONTROL]);
7003 hddLog(LOG1, FL("Control: %d"), control);
7004
7005 if (control == WLAN_START_OFFLOADED_PACKETS)
7006 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7007 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7008 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7009 else
7010 {
7011 hddLog(LOGE, FL("Invalid control: %d"), control);
7012 return -EINVAL;
7013 }
7014}
7015
7016/*
7017 * done with short names for the global vendor params
7018 * used by __wlan_hdd_cfg80211_offloaded_packets()
7019 */
7020#undef PARAM_MAX
7021#undef PARAM_REQUEST_ID
7022#undef PARAM_CONTROL
7023#undef PARAM_IP_PACKET
7024#undef PARAM_SRC_MAC_ADDR
7025#undef PARAM_DST_MAC_ADDR
7026#undef PARAM_PERIOD
7027
7028/**
7029 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7030 * @wiphy: wiphy structure pointer
7031 * @wdev: Wireless device structure pointer
7032 * @data: Pointer to the data received
7033 * @data_len: Length of @data
7034 *
7035 * Return: 0 on success; errno on failure
7036 */
7037static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7038 struct wireless_dev *wdev,
7039 const void *data,
7040 int data_len)
7041{
7042 int ret = 0;
7043
7044 vos_ssr_protect(__func__);
7045 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7046 wdev, data, data_len);
7047 vos_ssr_unprotect(__func__);
7048
7049 return ret;
7050}
7051#endif
7052
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307053static const struct
7054nla_policy
7055qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7056 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7057};
7058
7059/**
7060 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7061 * get link properties like nss, rate flags and operating frequency for
7062 * the connection with the given peer.
7063 * @wiphy: WIPHY structure pointer
7064 * @wdev: Wireless device structure pointer
7065 * @data: Pointer to the data received
7066 * @data_len: Length of the data received
7067 *
7068 * This function return the above link properties on success.
7069 *
7070 * Return: 0 on success and errno on failure
7071 */
7072static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7073 struct wireless_dev *wdev,
7074 const void *data,
7075 int data_len)
7076{
7077 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7078 struct net_device *dev = wdev->netdev;
7079 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7080 hdd_station_ctx_t *hdd_sta_ctx;
7081 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7082 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7083 uint32_t sta_id;
7084 struct sk_buff *reply_skb;
7085 uint32_t rate_flags = 0;
7086 uint8_t nss;
7087 uint8_t final_rate_flags = 0;
7088 uint32_t freq;
7089 v_CONTEXT_t pVosContext = NULL;
7090 ptSapContext pSapCtx = NULL;
7091
7092 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7093 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7094 return -EINVAL;
7095 }
7096
7097 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7098 qca_wlan_vendor_attr_policy)) {
7099 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7100 return -EINVAL;
7101 }
7102
7103 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7104 hddLog(VOS_TRACE_LEVEL_ERROR,
7105 FL("Attribute peerMac not provided for mode=%d"),
7106 adapter->device_mode);
7107 return -EINVAL;
7108 }
7109
7110 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7111 sizeof(peer_mac));
7112 hddLog(VOS_TRACE_LEVEL_INFO,
7113 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7114 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7115
7116 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7117 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7118 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7119 if ((hdd_sta_ctx->conn_info.connState !=
7120 eConnectionState_Associated) ||
7121 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7122 VOS_MAC_ADDRESS_LEN)) {
7123 hddLog(VOS_TRACE_LEVEL_ERROR,
7124 FL("Not Associated to mac "MAC_ADDRESS_STR),
7125 MAC_ADDR_ARRAY(peer_mac));
7126 return -EINVAL;
7127 }
7128
7129 nss = 1; //pronto supports only one spatial stream
7130 freq = vos_chan_to_freq(
7131 hdd_sta_ctx->conn_info.operationChannel);
7132 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7133
7134 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7135 adapter->device_mode == WLAN_HDD_SOFTAP) {
7136
7137 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7138 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7139 if(pSapCtx == NULL){
7140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7141 FL("psapCtx is NULL"));
7142 return -ENOENT;
7143 }
7144
7145
7146 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7147 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7148 !vos_is_macaddr_broadcast(
7149 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7150 vos_mem_compare(
7151 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7152 peer_mac, VOS_MAC_ADDRESS_LEN))
7153 break;
7154 }
7155
7156 if (WLAN_MAX_STA_COUNT == sta_id) {
7157 hddLog(VOS_TRACE_LEVEL_ERROR,
7158 FL("No active peer with mac="MAC_ADDRESS_STR),
7159 MAC_ADDR_ARRAY(peer_mac));
7160 return -EINVAL;
7161 }
7162
7163 nss = 1; //pronto supports only one spatial stream
7164 freq = vos_chan_to_freq(
7165 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7166 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7167 } else {
7168 hddLog(VOS_TRACE_LEVEL_ERROR,
7169 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7170 MAC_ADDR_ARRAY(peer_mac));
7171 return -EINVAL;
7172 }
7173
7174 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7175 if (rate_flags & eHAL_TX_RATE_VHT80) {
7176 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7177 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7178 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7179 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7180 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7181 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7182 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7183 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7184 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7185 if (rate_flags & eHAL_TX_RATE_HT40)
7186 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7187 }
7188
7189 if (rate_flags & eHAL_TX_RATE_SGI) {
7190 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7191 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7192 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7193 }
7194 }
7195
7196 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7197 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7198
7199 if (NULL == reply_skb) {
7200 hddLog(VOS_TRACE_LEVEL_ERROR,
7201 FL("getLinkProperties: skb alloc failed"));
7202 return -EINVAL;
7203 }
7204
7205 if (nla_put_u8(reply_skb,
7206 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7207 nss) ||
7208 nla_put_u8(reply_skb,
7209 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7210 final_rate_flags) ||
7211 nla_put_u32(reply_skb,
7212 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7213 freq)) {
7214 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7215 kfree_skb(reply_skb);
7216 return -EINVAL;
7217 }
7218
7219 return cfg80211_vendor_cmd_reply(reply_skb);
7220}
7221
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307222#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7223#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7224#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7225#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307226#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7227 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307228
7229/**
7230 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7231 * vendor command
7232 *
7233 * @wiphy: wiphy device pointer
7234 * @wdev: wireless device pointer
7235 * @data: Vendor command data buffer
7236 * @data_len: Buffer length
7237 *
7238 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7239 *
7240 * Return: EOK or other error codes.
7241 */
7242
7243static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7244 struct wireless_dev *wdev,
7245 const void *data,
7246 int data_len)
7247{
7248 struct net_device *dev = wdev->netdev;
7249 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7250 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7251 hdd_station_ctx_t *pHddStaCtx;
7252 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7253 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307254 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307255 eHalStatus status;
7256 int ret_val;
7257 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7258 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7259 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307260 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7261 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7262 { .type = NLA_U32},
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307263 };
7264
7265 ENTER();
7266
7267 if (VOS_FTM_MODE == hdd_get_conparam()) {
7268 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7269 return -EINVAL;
7270 }
7271
7272 ret_val = wlan_hdd_validate_context(pHddCtx);
7273 if (ret_val) {
7274 return ret_val;
7275 }
7276
7277 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7278
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307279 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7280 hddLog(LOGE, FL("Invalid ATTR"));
7281 return -EINVAL;
7282 }
7283
7284 /* check the Wifi Capability */
7285 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7286 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7287 {
7288 hddLog(VOS_TRACE_LEVEL_ERROR,
7289 FL("WIFICONFIG not supported by Firmware"));
7290 return -EINVAL;
7291 }
7292
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307293 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7294 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7295 modifyRoamParamsReq.value =
7296 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7297
7298 if (eHAL_STATUS_SUCCESS !=
7299 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7300 {
7301 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7302 ret_val = -EINVAL;
7303 }
7304 return ret_val;
7305 }
7306
7307 /* Moved this down in order to provide provision to set beacon
7308 * miss penalty count irrespective of connection state.
7309 */
7310 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7311 hddLog(LOGE, FL("Not in Connected state!"));
7312 return -ENOTSUPP;
7313 }
7314
7315 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307316
7317 if (!pReq) {
7318 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7319 "%s: Not able to allocate memory for tSetWifiConfigParams",
7320 __func__);
7321 return eHAL_STATUS_E_MALLOC_FAILED;
7322 }
7323
7324 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7325
7326 pReq->sessionId = pAdapter->sessionId;
7327 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7328
7329 if (tb[PARAM_MODULATED_DTIM]) {
7330 pReq->paramValue = nla_get_u32(
7331 tb[PARAM_MODULATED_DTIM]);
7332 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7333 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307334 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307335 hdd_set_pwrparams(pHddCtx);
7336 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7337 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7338
7339 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7340 iw_full_power_cbfn, pAdapter,
7341 eSME_FULL_PWR_NEEDED_BY_HDD);
7342 }
7343 else
7344 {
7345 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7346 }
7347 }
7348
7349 if (tb[PARAM_STATS_AVG_FACTOR]) {
7350 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7351 pReq->paramValue = nla_get_u16(
7352 tb[PARAM_STATS_AVG_FACTOR]);
7353 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7354 pReq->paramType, pReq->paramValue);
7355 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7356
7357 if (eHAL_STATUS_SUCCESS != status)
7358 {
7359 vos_mem_free(pReq);
7360 pReq = NULL;
7361 ret_val = -EPERM;
7362 return ret_val;
7363 }
7364 }
7365
7366
7367 if (tb[PARAM_GUARD_TIME]) {
7368 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7369 pReq->paramValue = nla_get_u32(
7370 tb[PARAM_GUARD_TIME]);
7371 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7372 pReq->paramType, pReq->paramValue);
7373 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7374
7375 if (eHAL_STATUS_SUCCESS != status)
7376 {
7377 vos_mem_free(pReq);
7378 pReq = NULL;
7379 ret_val = -EPERM;
7380 return ret_val;
7381 }
7382
7383 }
7384
7385 EXIT();
7386 return ret_val;
7387}
7388
7389/**
7390 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7391 * vendor command
7392 *
7393 * @wiphy: wiphy device pointer
7394 * @wdev: wireless device pointer
7395 * @data: Vendor command data buffer
7396 * @data_len: Buffer length
7397 *
7398 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7399 *
7400 * Return: EOK or other error codes.
7401 */
7402static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7403 struct wireless_dev *wdev,
7404 const void *data,
7405 int data_len)
7406{
7407 int ret;
7408
7409 vos_ssr_protect(__func__);
7410 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7411 data, data_len);
7412 vos_ssr_unprotect(__func__);
7413
7414 return ret;
7415}
Sunil Duttc69bccb2014-05-26 21:30:20 +05307416const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7417{
Mukul Sharma2a271632014-10-13 14:59:01 +05307418 {
7419 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7420 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7421 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7422 WIPHY_VENDOR_CMD_NEED_NETDEV |
7423 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307424 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307425 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307426
7427 {
7428 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7429 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7430 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7431 WIPHY_VENDOR_CMD_NEED_NETDEV |
7432 WIPHY_VENDOR_CMD_NEED_RUNNING,
7433 .doit = wlan_hdd_cfg80211_nan_request
7434 },
7435
Sunil Duttc69bccb2014-05-26 21:30:20 +05307436#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7437 {
7438 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7439 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7440 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7441 WIPHY_VENDOR_CMD_NEED_NETDEV |
7442 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307443 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307444 },
7445
7446 {
7447 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7448 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7449 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7450 WIPHY_VENDOR_CMD_NEED_NETDEV |
7451 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307452 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307453 },
7454
7455 {
7456 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7457 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7458 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7459 WIPHY_VENDOR_CMD_NEED_NETDEV |
7460 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307461 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307462 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307463#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307464#ifdef WLAN_FEATURE_EXTSCAN
7465 {
7466 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7467 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7468 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7469 WIPHY_VENDOR_CMD_NEED_NETDEV |
7470 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307471 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307472 },
7473 {
7474 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7475 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7476 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7477 WIPHY_VENDOR_CMD_NEED_NETDEV |
7478 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307479 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307480 },
7481 {
7482 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7483 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7484 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7485 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307486 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307487 },
7488 {
7489 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7490 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7491 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7492 WIPHY_VENDOR_CMD_NEED_NETDEV |
7493 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307494 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307495 },
7496 {
7497 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7498 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7499 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7500 WIPHY_VENDOR_CMD_NEED_NETDEV |
7501 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307502 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307503 },
7504 {
7505 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7506 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7507 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7508 WIPHY_VENDOR_CMD_NEED_NETDEV |
7509 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307510 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307511 },
7512 {
7513 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7514 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7515 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7516 WIPHY_VENDOR_CMD_NEED_NETDEV |
7517 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307518 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307519 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307520 {
7521 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7522 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7523 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7524 WIPHY_VENDOR_CMD_NEED_NETDEV |
7525 WIPHY_VENDOR_CMD_NEED_RUNNING,
7526 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7527 },
7528 {
7529 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7530 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7531 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7532 WIPHY_VENDOR_CMD_NEED_NETDEV |
7533 WIPHY_VENDOR_CMD_NEED_RUNNING,
7534 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7535 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307536#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307537/*EXT TDLS*/
7538 {
7539 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7540 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7541 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7542 WIPHY_VENDOR_CMD_NEED_NETDEV |
7543 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307544 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307545 },
7546 {
7547 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7548 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7549 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7550 WIPHY_VENDOR_CMD_NEED_NETDEV |
7551 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307552 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307553 },
7554 {
7555 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7556 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7557 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7558 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307559 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307560 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307561 {
7562 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7563 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7564 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7565 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307566 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307567 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307568 {
7569 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7570 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7571 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7572 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307573 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307574 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307575 {
7576 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7577 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7578 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7579 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307580 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307581 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307582 {
7583 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7584 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7585 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7586 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307587 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307588 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307589 {
7590 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307591 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7592 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7593 WIPHY_VENDOR_CMD_NEED_NETDEV |
7594 WIPHY_VENDOR_CMD_NEED_RUNNING,
7595 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7596 },
7597 {
7598 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307599 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7600 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7601 WIPHY_VENDOR_CMD_NEED_NETDEV |
7602 WIPHY_VENDOR_CMD_NEED_RUNNING,
7603 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307604 },
7605 {
7606 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7607 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7608 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7609 WIPHY_VENDOR_CMD_NEED_NETDEV,
7610 .doit = wlan_hdd_cfg80211_wifi_logger_start
7611 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307612 {
7613 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7614 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7615 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7616 WIPHY_VENDOR_CMD_NEED_NETDEV|
7617 WIPHY_VENDOR_CMD_NEED_RUNNING,
7618 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307619 },
7620 {
7621 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7622 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7623 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7624 WIPHY_VENDOR_CMD_NEED_NETDEV |
7625 WIPHY_VENDOR_CMD_NEED_RUNNING,
7626 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307627 },
7628 {
7629 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7630 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7631 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7632 WIPHY_VENDOR_CMD_NEED_NETDEV |
7633 WIPHY_VENDOR_CMD_NEED_RUNNING,
7634 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307635 },
7636#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7637 {
7638 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7639 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7640 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7641 WIPHY_VENDOR_CMD_NEED_NETDEV |
7642 WIPHY_VENDOR_CMD_NEED_RUNNING,
7643 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307644 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307645#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307646 {
7647 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7648 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7649 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7650 WIPHY_VENDOR_CMD_NEED_NETDEV |
7651 WIPHY_VENDOR_CMD_NEED_RUNNING,
7652 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307653 },
7654 {
7655 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7656 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7657 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7658 WIPHY_VENDOR_CMD_NEED_NETDEV |
7659 WIPHY_VENDOR_CMD_NEED_RUNNING,
7660 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307661 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05307662};
7663
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007664/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307665static const
7666struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007667{
7668#ifdef FEATURE_WLAN_CH_AVOID
7669 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307670 .vendor_id = QCA_NL80211_VENDOR_ID,
7671 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007672 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307673#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7674#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7675 {
7676 /* Index = 1*/
7677 .vendor_id = QCA_NL80211_VENDOR_ID,
7678 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7679 },
7680 {
7681 /* Index = 2*/
7682 .vendor_id = QCA_NL80211_VENDOR_ID,
7683 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7684 },
7685 {
7686 /* Index = 3*/
7687 .vendor_id = QCA_NL80211_VENDOR_ID,
7688 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7689 },
7690 {
7691 /* Index = 4*/
7692 .vendor_id = QCA_NL80211_VENDOR_ID,
7693 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7694 },
7695 {
7696 /* Index = 5*/
7697 .vendor_id = QCA_NL80211_VENDOR_ID,
7698 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7699 },
7700 {
7701 /* Index = 6*/
7702 .vendor_id = QCA_NL80211_VENDOR_ID,
7703 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7704 },
7705#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307706#ifdef WLAN_FEATURE_EXTSCAN
7707 {
7708 .vendor_id = QCA_NL80211_VENDOR_ID,
7709 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7710 },
7711 {
7712 .vendor_id = QCA_NL80211_VENDOR_ID,
7713 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7714 },
7715 {
7716 .vendor_id = QCA_NL80211_VENDOR_ID,
7717 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7718 },
7719 {
7720 .vendor_id = QCA_NL80211_VENDOR_ID,
7721 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7722 },
7723 {
7724 .vendor_id = QCA_NL80211_VENDOR_ID,
7725 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7726 },
7727 {
7728 .vendor_id = QCA_NL80211_VENDOR_ID,
7729 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7730 },
7731 {
7732 .vendor_id = QCA_NL80211_VENDOR_ID,
7733 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7734 },
7735 {
7736 .vendor_id = QCA_NL80211_VENDOR_ID,
7737 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7738 },
7739 {
7740 .vendor_id = QCA_NL80211_VENDOR_ID,
7741 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7742 },
7743 {
7744 .vendor_id = QCA_NL80211_VENDOR_ID,
7745 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7746 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307747 {
7748 .vendor_id = QCA_NL80211_VENDOR_ID,
7749 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7750 },
7751 {
7752 .vendor_id = QCA_NL80211_VENDOR_ID,
7753 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7754 },
7755 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7756 .vendor_id = QCA_NL80211_VENDOR_ID,
7757 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7758 },
7759 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7760 .vendor_id = QCA_NL80211_VENDOR_ID,
7761 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7762 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307763#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307764/*EXT TDLS*/
7765 {
7766 .vendor_id = QCA_NL80211_VENDOR_ID,
7767 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7768 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307769 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7770 .vendor_id = QCA_NL80211_VENDOR_ID,
7771 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7772 },
7773
Srinivas Dasari030bad32015-02-18 23:23:54 +05307774
7775 {
7776 .vendor_id = QCA_NL80211_VENDOR_ID,
7777 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7778 },
7779
Sushant Kaushik084f6592015-09-10 13:11:56 +05307780 {
7781 .vendor_id = QCA_NL80211_VENDOR_ID,
7782 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307783 },
7784 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7785 .vendor_id = QCA_NL80211_VENDOR_ID,
7786 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7787 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05307788 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
7789 .vendor_id = QCA_NL80211_VENDOR_ID,
7790 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
7791 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307792
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007793};
7794
Jeff Johnson295189b2012-06-20 16:38:30 -07007795/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307796 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307797 * This function is called by hdd_wlan_startup()
7798 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307799 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007800 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307801struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007802{
7803 struct wiphy *wiphy;
7804 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307805 /*
7806 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007807 */
7808 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7809
7810 if (!wiphy)
7811 {
7812 /* Print error and jump into err label and free the memory */
7813 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7814 return NULL;
7815 }
7816
Sunil Duttc69bccb2014-05-26 21:30:20 +05307817
Jeff Johnson295189b2012-06-20 16:38:30 -07007818 return wiphy;
7819}
7820
7821/*
7822 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307823 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007824 * private ioctl to change the band value
7825 */
7826int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7827{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307828 int i, j;
7829 eNVChannelEnabledType channelEnabledState;
7830
Jeff Johnsone7245742012-09-05 17:12:55 -07007831 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307832
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307833 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007834 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307835
7836 if (NULL == wiphy->bands[i])
7837 {
7838 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7839 __func__, i);
7840 continue;
7841 }
7842
7843 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7844 {
7845 struct ieee80211_supported_band *band = wiphy->bands[i];
7846
7847 channelEnabledState = vos_nv_getChannelEnabledState(
7848 band->channels[j].hw_value);
7849
7850 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7851 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307852 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307853 continue;
7854 }
7855 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7856 {
7857 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7858 continue;
7859 }
7860
7861 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7862 NV_CHANNEL_INVALID == channelEnabledState)
7863 {
7864 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7865 }
7866 else if (NV_CHANNEL_DFS == channelEnabledState)
7867 {
7868 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7869 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7870 }
7871 else
7872 {
7873 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7874 |IEEE80211_CHAN_RADAR);
7875 }
7876 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007877 }
7878 return 0;
7879}
7880/*
7881 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307882 * This function is called by hdd_wlan_startup()
7883 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007884 * This function is used to initialize and register wiphy structure.
7885 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307886int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007887 struct wiphy *wiphy,
7888 hdd_config_t *pCfg
7889 )
7890{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307891 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307892 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7893
Jeff Johnsone7245742012-09-05 17:12:55 -07007894 ENTER();
7895
Jeff Johnson295189b2012-06-20 16:38:30 -07007896 /* Now bind the underlying wlan device with wiphy */
7897 set_wiphy_dev(wiphy, dev);
7898
7899 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007900
Kiet Lam6c583332013-10-14 05:37:09 +05307901#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007902 /* the flag for the other case would be initialzed in
7903 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05307904#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7905 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
7906#else
Amar Singhal0a402232013-10-11 20:57:16 -07007907 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307908#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05307909#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007910
Amar Singhalfddc28c2013-09-05 13:03:40 -07007911 /* This will disable updating of NL channels from passive to
7912 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307913#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7914 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7915#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007916 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307917#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007918
Amar Singhala49cbc52013-10-08 18:37:44 -07007919
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007920#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007921 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7922 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7923 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007924 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307925#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05307926 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307927#else
7928 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7929#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007930#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007931
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007932#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007933 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007934#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007935 || pCfg->isFastRoamIniFeatureEnabled
7936#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007937#ifdef FEATURE_WLAN_ESE
7938 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007939#endif
7940 )
7941 {
7942 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7943 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007944#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007945#ifdef FEATURE_WLAN_TDLS
7946 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7947 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7948#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307949#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307950 if (pCfg->configPNOScanSupport)
7951 {
7952 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7953 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7954 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7955 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7956 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307957#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007958
Abhishek Singh10d85972015-04-17 10:27:23 +05307959#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7960 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7961#endif
7962
Amar Singhalfddc28c2013-09-05 13:03:40 -07007963#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007964 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
7965 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07007966 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007967 driver need to determine what to do with both
7968 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07007969
7970 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07007971#else
7972 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007973#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007974
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307975 wiphy->max_scan_ssids = MAX_SCAN_SSID;
7976
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05307977 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07007978
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307979 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
7980
Jeff Johnson295189b2012-06-20 16:38:30 -07007981 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05307982 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
7983 | BIT(NL80211_IFTYPE_ADHOC)
7984 | BIT(NL80211_IFTYPE_P2P_CLIENT)
7985 | BIT(NL80211_IFTYPE_P2P_GO)
7986 | BIT(NL80211_IFTYPE_AP);
7987
7988 if (VOS_MONITOR_MODE == hdd_get_conparam())
7989 {
7990 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
7991 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007992
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307993 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007994 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307995#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7996 if( pCfg->enableMCC )
7997 {
7998 /* Currently, supports up to two channels */
7999 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008000
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308001 if( !pCfg->allowMCCGODiffBI )
8002 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008003
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308004 }
8005 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8006 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008007#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308008 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008009
Jeff Johnson295189b2012-06-20 16:38:30 -07008010 /* Before registering we need to update the ht capabilitied based
8011 * on ini values*/
8012 if( !pCfg->ShortGI20MhzEnable )
8013 {
8014 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8015 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008016 }
8017
8018 if( !pCfg->ShortGI40MhzEnable )
8019 {
8020 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8021 }
8022
8023 if( !pCfg->nChannelBondingMode5GHz )
8024 {
8025 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8026 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308027 /*
8028 * In case of static linked driver at the time of driver unload,
8029 * module exit doesn't happens. Module cleanup helps in cleaning
8030 * of static memory.
8031 * If driver load happens statically, at the time of driver unload,
8032 * wiphy flags don't get reset because of static memory.
8033 * It's better not to store channel in static memory.
8034 */
8035 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8036 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8037 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8038 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8039 {
8040 hddLog(VOS_TRACE_LEVEL_ERROR,
8041 FL("Not enough memory to allocate channels"));
8042 return -ENOMEM;
8043 }
8044 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8045 &hdd_channels_2_4_GHZ[0],
8046 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008047
Agrawal Ashish97dec502015-11-26 20:20:58 +05308048 if (true == hdd_is_5g_supported(pHddCtx))
8049 {
8050 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8051 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8052 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8053 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8054 {
8055 hddLog(VOS_TRACE_LEVEL_ERROR,
8056 FL("Not enough memory to allocate channels"));
8057 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8058 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8059 return -ENOMEM;
8060 }
8061 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8062 &hdd_channels_5_GHZ[0],
8063 sizeof(hdd_channels_5_GHZ));
8064 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308065
8066 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8067 {
8068
8069 if (NULL == wiphy->bands[i])
8070 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308071 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308072 __func__, i);
8073 continue;
8074 }
8075
8076 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8077 {
8078 struct ieee80211_supported_band *band = wiphy->bands[i];
8079
8080 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8081 {
8082 // Enable social channels for P2P
8083 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8084 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8085 else
8086 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8087 continue;
8088 }
8089 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8090 {
8091 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8092 continue;
8093 }
8094 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008095 }
8096 /*Initialise the supported cipher suite details*/
8097 wiphy->cipher_suites = hdd_cipher_suites;
8098 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8099
8100 /*signal strength in mBm (100*dBm) */
8101 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8102
8103#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308104 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008105#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008106
Sunil Duttc69bccb2014-05-26 21:30:20 +05308107 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8108 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008109 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8110 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8111
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308112 EXIT();
8113 return 0;
8114}
8115
8116/* In this function we are registering wiphy. */
8117int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8118{
8119 ENTER();
8120 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008121 if (0 > wiphy_register(wiphy))
8122 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308123 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008124 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8125 return -EIO;
8126 }
8127
8128 EXIT();
8129 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308130}
Jeff Johnson295189b2012-06-20 16:38:30 -07008131
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308132/* In this function we are updating channel list when,
8133 regulatory domain is FCC and country code is US.
8134 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8135 As per FCC smart phone is not a indoor device.
8136 GO should not opeate on indoor channels */
8137void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8138{
8139 int j;
8140 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8141 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8142 //Default counrtycode from NV at the time of wiphy initialization.
8143 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8144 &defaultCountryCode[0]))
8145 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008146 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308147 }
8148 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8149 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308150 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8151 {
8152 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8153 return;
8154 }
8155 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8156 {
8157 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8158 // Mark UNII -1 band channel as passive
8159 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8160 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8161 }
8162 }
8163}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308164/* This function registers for all frame which supplicant is interested in */
8165void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008166{
Jeff Johnson295189b2012-06-20 16:38:30 -07008167 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8168 /* Register for all P2P action, public action etc frames */
8169 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008170 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308171 /* Register frame indication call back */
8172 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008173 /* Right now we are registering these frame when driver is getting
8174 initialized. Once we will move to 2.6.37 kernel, in which we have
8175 frame register ops, we will move this code as a part of that */
8176 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308177 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008178 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8179
8180 /* GAS Initial Response */
8181 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8182 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308183
Jeff Johnson295189b2012-06-20 16:38:30 -07008184 /* GAS Comeback Request */
8185 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8186 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8187
8188 /* GAS Comeback Response */
8189 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8190 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8191
8192 /* P2P Public Action */
8193 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308194 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008195 P2P_PUBLIC_ACTION_FRAME_SIZE );
8196
8197 /* P2P Action */
8198 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8199 (v_U8_t*)P2P_ACTION_FRAME,
8200 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008201
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308202 /* WNM BSS Transition Request frame */
8203 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8204 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8205 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008206
8207 /* WNM-Notification */
8208 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8209 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8210 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008211}
8212
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308213void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008214{
Jeff Johnson295189b2012-06-20 16:38:30 -07008215 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8216 /* Register for all P2P action, public action etc frames */
8217 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8218
Jeff Johnsone7245742012-09-05 17:12:55 -07008219 ENTER();
8220
Jeff Johnson295189b2012-06-20 16:38:30 -07008221 /* Right now we are registering these frame when driver is getting
8222 initialized. Once we will move to 2.6.37 kernel, in which we have
8223 frame register ops, we will move this code as a part of that */
8224 /* GAS Initial Request */
8225
8226 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8227 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8228
8229 /* GAS Initial Response */
8230 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8231 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308232
Jeff Johnson295189b2012-06-20 16:38:30 -07008233 /* GAS Comeback Request */
8234 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8235 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8236
8237 /* GAS Comeback Response */
8238 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8239 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8240
8241 /* P2P Public Action */
8242 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308243 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008244 P2P_PUBLIC_ACTION_FRAME_SIZE );
8245
8246 /* P2P Action */
8247 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8248 (v_U8_t*)P2P_ACTION_FRAME,
8249 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008250 /* WNM-Notification */
8251 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8252 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8253 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008254}
8255
8256#ifdef FEATURE_WLAN_WAPI
8257void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308258 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008259{
8260 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8261 tCsrRoamSetKey setKey;
8262 v_BOOL_t isConnected = TRUE;
8263 int status = 0;
8264 v_U32_t roamId= 0xFF;
8265 tANI_U8 *pKeyPtr = NULL;
8266 int n = 0;
8267
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308268 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8269 __func__, hdd_device_modetoString(pAdapter->device_mode),
8270 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008271
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308272 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008273 setKey.keyId = key_index; // Store Key ID
8274 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8275 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8276 setKey.paeRole = 0 ; // the PAE role
8277 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8278 {
8279 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8280 }
8281 else
8282 {
8283 isConnected = hdd_connIsConnected(pHddStaCtx);
8284 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8285 }
8286 setKey.keyLength = key_Len;
8287 pKeyPtr = setKey.Key;
8288 memcpy( pKeyPtr, key, key_Len);
8289
Arif Hussain6d2a3322013-11-17 19:50:10 -08008290 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008291 __func__, key_Len);
8292 for (n = 0 ; n < key_Len; n++)
8293 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8294 __func__,n,setKey.Key[n]);
8295
8296 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8297 if ( isConnected )
8298 {
8299 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8300 pAdapter->sessionId, &setKey, &roamId );
8301 }
8302 if ( status != 0 )
8303 {
8304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8305 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8306 __LINE__, status );
8307 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8308 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308309 /* Need to clear any trace of key value in the memory.
8310 * Thus zero out the memory even though it is local
8311 * variable.
8312 */
8313 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008314}
8315#endif /* FEATURE_WLAN_WAPI*/
8316
8317#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308318int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008319 beacon_data_t **ppBeacon,
8320 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008321#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308322int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008323 beacon_data_t **ppBeacon,
8324 struct cfg80211_beacon_data *params,
8325 int dtim_period)
8326#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308327{
Jeff Johnson295189b2012-06-20 16:38:30 -07008328 int size;
8329 beacon_data_t *beacon = NULL;
8330 beacon_data_t *old = NULL;
8331 int head_len,tail_len;
8332
Jeff Johnsone7245742012-09-05 17:12:55 -07008333 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008334 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308335 {
8336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8337 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008338 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308339 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008340
8341 old = pAdapter->sessionCtx.ap.beacon;
8342
8343 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308344 {
8345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8346 FL("session(%d) old and new heads points to NULL"),
8347 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008348 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308349 }
8350
8351 if (params->tail && !params->tail_len)
8352 {
8353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8354 FL("tail_len is zero but tail is not NULL"));
8355 return -EINVAL;
8356 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008357
Jeff Johnson295189b2012-06-20 16:38:30 -07008358#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8359 /* Kernel 3.0 is not updating dtim_period for set beacon */
8360 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308361 {
8362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8363 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008364 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308365 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008366#endif
8367
8368 if(params->head)
8369 head_len = params->head_len;
8370 else
8371 head_len = old->head_len;
8372
8373 if(params->tail || !old)
8374 tail_len = params->tail_len;
8375 else
8376 tail_len = old->tail_len;
8377
8378 size = sizeof(beacon_data_t) + head_len + tail_len;
8379
8380 beacon = kzalloc(size, GFP_KERNEL);
8381
8382 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308383 {
8384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8385 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008386 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308387 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008388
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008389#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008390 if(params->dtim_period || !old )
8391 beacon->dtim_period = params->dtim_period;
8392 else
8393 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008394#else
8395 if(dtim_period || !old )
8396 beacon->dtim_period = dtim_period;
8397 else
8398 beacon->dtim_period = old->dtim_period;
8399#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308400
Jeff Johnson295189b2012-06-20 16:38:30 -07008401 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8402 beacon->tail = beacon->head + head_len;
8403 beacon->head_len = head_len;
8404 beacon->tail_len = tail_len;
8405
8406 if(params->head) {
8407 memcpy (beacon->head,params->head,beacon->head_len);
8408 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308409 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07008410 if(old)
8411 memcpy (beacon->head,old->head,beacon->head_len);
8412 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308413
Jeff Johnson295189b2012-06-20 16:38:30 -07008414 if(params->tail) {
8415 memcpy (beacon->tail,params->tail,beacon->tail_len);
8416 }
8417 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308418 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07008419 memcpy (beacon->tail,old->tail,beacon->tail_len);
8420 }
8421
8422 *ppBeacon = beacon;
8423
8424 kfree(old);
8425
8426 return 0;
8427
8428}
Jeff Johnson295189b2012-06-20 16:38:30 -07008429
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308430v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8431#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8432 const v_U8_t *pIes,
8433#else
8434 v_U8_t *pIes,
8435#endif
8436 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008437{
8438 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308439 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308441
Jeff Johnson295189b2012-06-20 16:38:30 -07008442 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308443 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008444 elem_id = ptr[0];
8445 elem_len = ptr[1];
8446 left -= 2;
8447 if(elem_len > left)
8448 {
8449 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008450 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008451 eid,elem_len,left);
8452 return NULL;
8453 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308454 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008455 {
8456 return ptr;
8457 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308458
Jeff Johnson295189b2012-06-20 16:38:30 -07008459 left -= elem_len;
8460 ptr += (elem_len + 2);
8461 }
8462 return NULL;
8463}
8464
Jeff Johnson295189b2012-06-20 16:38:30 -07008465/* Check if rate is 11g rate or not */
8466static int wlan_hdd_rate_is_11g(u8 rate)
8467{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008468 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008469 u8 i;
8470 for (i = 0; i < 8; i++)
8471 {
8472 if(rate == gRateArray[i])
8473 return TRUE;
8474 }
8475 return FALSE;
8476}
8477
8478/* Check for 11g rate and set proper 11g only mode */
8479static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8480 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8481{
8482 u8 i, num_rates = pIe[0];
8483
8484 pIe += 1;
8485 for ( i = 0; i < num_rates; i++)
8486 {
8487 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8488 {
8489 /* If rate set have 11g rate than change the mode to 11G */
8490 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8491 if (pIe[i] & BASIC_RATE_MASK)
8492 {
8493 /* If we have 11g rate as basic rate, it means mode
8494 is 11g only mode.
8495 */
8496 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8497 *pCheckRatesfor11g = FALSE;
8498 }
8499 }
8500 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8501 {
8502 *require_ht = TRUE;
8503 }
8504 }
8505 return;
8506}
8507
8508static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8509{
8510 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8511 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8512 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8513 u8 checkRatesfor11g = TRUE;
8514 u8 require_ht = FALSE;
8515 u8 *pIe=NULL;
8516
8517 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8518
8519 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8520 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8521 if (pIe != NULL)
8522 {
8523 pIe += 1;
8524 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8525 &pConfig->SapHw_mode);
8526 }
8527
8528 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8529 WLAN_EID_EXT_SUPP_RATES);
8530 if (pIe != NULL)
8531 {
8532
8533 pIe += 1;
8534 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8535 &pConfig->SapHw_mode);
8536 }
8537
8538 if( pConfig->channel > 14 )
8539 {
8540 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8541 }
8542
8543 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8544 WLAN_EID_HT_CAPABILITY);
8545
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308546 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008547 {
8548 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8549 if(require_ht)
8550 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8551 }
8552}
8553
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308554static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8555 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8556{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008557 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308558 v_U8_t *pIe = NULL;
8559 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8560
8561 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8562 pBeacon->tail, pBeacon->tail_len);
8563
8564 if (pIe)
8565 {
8566 ielen = pIe[1] + 2;
8567 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8568 {
8569 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8570 }
8571 else
8572 {
8573 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8574 return -EINVAL;
8575 }
8576 *total_ielen += ielen;
8577 }
8578 return 0;
8579}
8580
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008581static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8582 v_U8_t *genie, v_U8_t *total_ielen)
8583{
8584 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8585 int left = pBeacon->tail_len;
8586 v_U8_t *ptr = pBeacon->tail;
8587 v_U8_t elem_id, elem_len;
8588 v_U16_t ielen = 0;
8589
8590 if ( NULL == ptr || 0 == left )
8591 return;
8592
8593 while (left >= 2)
8594 {
8595 elem_id = ptr[0];
8596 elem_len = ptr[1];
8597 left -= 2;
8598 if (elem_len > left)
8599 {
8600 hddLog( VOS_TRACE_LEVEL_ERROR,
8601 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8602 elem_id, elem_len, left);
8603 return;
8604 }
8605 if (IE_EID_VENDOR == elem_id)
8606 {
8607 /* skipping the VSIE's which we don't want to include or
8608 * it will be included by existing code
8609 */
8610 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8611#ifdef WLAN_FEATURE_WFD
8612 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8613#endif
8614 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8615 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8616 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8617 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8618 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8619 {
8620 ielen = ptr[1] + 2;
8621 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8622 {
8623 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8624 *total_ielen += ielen;
8625 }
8626 else
8627 {
8628 hddLog( VOS_TRACE_LEVEL_ERROR,
8629 "IE Length is too big "
8630 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8631 elem_id, elem_len, *total_ielen);
8632 }
8633 }
8634 }
8635
8636 left -= elem_len;
8637 ptr += (elem_len + 2);
8638 }
8639 return;
8640}
8641
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008642#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008643static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8644 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008645#else
8646static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8647 struct cfg80211_beacon_data *params)
8648#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008649{
8650 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308651 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008652 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008653 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008654
8655 genie = vos_mem_malloc(MAX_GENIE_LEN);
8656
8657 if(genie == NULL) {
8658
8659 return -ENOMEM;
8660 }
8661
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308662 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8663 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008664 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308665 hddLog(LOGE,
8666 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308667 ret = -EINVAL;
8668 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008669 }
8670
8671#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308672 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8673 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8674 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308675 hddLog(LOGE,
8676 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308677 ret = -EINVAL;
8678 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008679 }
8680#endif
8681
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308682 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8683 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008684 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308685 hddLog(LOGE,
8686 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308687 ret = -EINVAL;
8688 goto done;
8689 }
8690
8691 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8692 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008693 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008694 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008695
8696 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8697 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8698 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8699 {
8700 hddLog(LOGE,
8701 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008702 ret = -EINVAL;
8703 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008704 }
8705
8706 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8707 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8708 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8709 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8710 ==eHAL_STATUS_FAILURE)
8711 {
8712 hddLog(LOGE,
8713 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008714 ret = -EINVAL;
8715 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008716 }
8717
8718 // Added for ProResp IE
8719 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
8720 {
8721 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
8722 u8 probe_rsp_ie_len[3] = {0};
8723 u8 counter = 0;
8724 /* Check Probe Resp Length if it is greater then 255 then Store
8725 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8726 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8727 Store More then 255 bytes into One Variable.
8728 */
8729 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8730 {
8731 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8732 {
8733 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8734 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8735 }
8736 else
8737 {
8738 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8739 rem_probe_resp_ie_len = 0;
8740 }
8741 }
8742
8743 rem_probe_resp_ie_len = 0;
8744
8745 if (probe_rsp_ie_len[0] > 0)
8746 {
8747 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8748 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
8749 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8750 probe_rsp_ie_len[0], NULL,
8751 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8752 {
8753 hddLog(LOGE,
8754 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008755 ret = -EINVAL;
8756 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008757 }
8758 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8759 }
8760
8761 if (probe_rsp_ie_len[1] > 0)
8762 {
8763 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8764 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
8765 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8766 probe_rsp_ie_len[1], NULL,
8767 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8768 {
8769 hddLog(LOGE,
8770 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008771 ret = -EINVAL;
8772 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008773 }
8774 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8775 }
8776
8777 if (probe_rsp_ie_len[2] > 0)
8778 {
8779 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8780 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
8781 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8782 probe_rsp_ie_len[2], NULL,
8783 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8784 {
8785 hddLog(LOGE,
8786 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008787 ret = -EINVAL;
8788 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 }
8790 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8791 }
8792
8793 if (probe_rsp_ie_len[1] == 0 )
8794 {
8795 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8796 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8797 eANI_BOOLEAN_FALSE) )
8798 {
8799 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008800 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008801 }
8802 }
8803
8804 if (probe_rsp_ie_len[2] == 0 )
8805 {
8806 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8807 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8808 eANI_BOOLEAN_FALSE) )
8809 {
8810 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008811 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008812 }
8813 }
8814
8815 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8816 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8817 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8818 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8819 == eHAL_STATUS_FAILURE)
8820 {
8821 hddLog(LOGE,
8822 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008823 ret = -EINVAL;
8824 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008825 }
8826 }
8827 else
8828 {
8829 // Reset WNI_CFG_PROBE_RSP Flags
8830 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8831
8832 hddLog(VOS_TRACE_LEVEL_INFO,
8833 "%s: No Probe Response IE received in set beacon",
8834 __func__);
8835 }
8836
8837 // Added for AssocResp IE
8838 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
8839 {
8840 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8841 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
8842 params->assocresp_ies_len, NULL,
8843 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8844 {
8845 hddLog(LOGE,
8846 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008847 ret = -EINVAL;
8848 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008849 }
8850
8851 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8852 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8853 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8854 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8855 == eHAL_STATUS_FAILURE)
8856 {
8857 hddLog(LOGE,
8858 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008859 ret = -EINVAL;
8860 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008861 }
8862 }
8863 else
8864 {
8865 hddLog(VOS_TRACE_LEVEL_INFO,
8866 "%s: No Assoc Response IE received in set beacon",
8867 __func__);
8868
8869 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8870 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8871 eANI_BOOLEAN_FALSE) )
8872 {
8873 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008874 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008875 }
8876 }
8877
Jeff Johnsone7245742012-09-05 17:12:55 -07008878done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008879 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308880 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008881}
Jeff Johnson295189b2012-06-20 16:38:30 -07008882
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308883/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008884 * FUNCTION: wlan_hdd_validate_operation_channel
8885 * called by wlan_hdd_cfg80211_start_bss() and
8886 * wlan_hdd_cfg80211_set_channel()
8887 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308888 * channel list.
8889 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008890VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008891{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308892
Jeff Johnson295189b2012-06-20 16:38:30 -07008893 v_U32_t num_ch = 0;
8894 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8895 u32 indx = 0;
8896 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308897 v_U8_t fValidChannel = FALSE, count = 0;
8898 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308899
Jeff Johnson295189b2012-06-20 16:38:30 -07008900 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8901
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308902 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008903 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308904 /* Validate the channel */
8905 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008906 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308907 if ( channel == rfChannels[count].channelNum )
8908 {
8909 fValidChannel = TRUE;
8910 break;
8911 }
8912 }
8913 if (fValidChannel != TRUE)
8914 {
8915 hddLog(VOS_TRACE_LEVEL_ERROR,
8916 "%s: Invalid Channel [%d]", __func__, channel);
8917 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008918 }
8919 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308920 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008921 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308922 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8923 valid_ch, &num_ch))
8924 {
8925 hddLog(VOS_TRACE_LEVEL_ERROR,
8926 "%s: failed to get valid channel list", __func__);
8927 return VOS_STATUS_E_FAILURE;
8928 }
8929 for (indx = 0; indx < num_ch; indx++)
8930 {
8931 if (channel == valid_ch[indx])
8932 {
8933 break;
8934 }
8935 }
8936
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308937 if (indx >= num_ch)
8938 {
8939 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8940 {
8941 eCsrBand band;
8942 unsigned int freq;
8943
8944 sme_GetFreqBand(hHal, &band);
8945
8946 if (eCSR_BAND_5G == band)
8947 {
8948#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8949 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8950 {
8951 freq = ieee80211_channel_to_frequency(channel,
8952 IEEE80211_BAND_2GHZ);
8953 }
8954 else
8955 {
8956 freq = ieee80211_channel_to_frequency(channel,
8957 IEEE80211_BAND_5GHZ);
8958 }
8959#else
8960 freq = ieee80211_channel_to_frequency(channel);
8961#endif
8962 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
8963 return VOS_STATUS_SUCCESS;
8964 }
8965 }
8966
8967 hddLog(VOS_TRACE_LEVEL_ERROR,
8968 "%s: Invalid Channel [%d]", __func__, channel);
8969 return VOS_STATUS_E_FAILURE;
8970 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008971 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308972
Jeff Johnson295189b2012-06-20 16:38:30 -07008973 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308974
Jeff Johnson295189b2012-06-20 16:38:30 -07008975}
8976
Viral Modi3a32cc52013-02-08 11:14:52 -08008977/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308978 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08008979 * This function is used to set the channel number
8980 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308981static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08008982 struct ieee80211_channel *chan,
8983 enum nl80211_channel_type channel_type
8984 )
8985{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308986 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08008987 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07008988 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08008989 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308990 hdd_context_t *pHddCtx;
8991 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008992
8993 ENTER();
8994
8995 if( NULL == dev )
8996 {
8997 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008998 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08008999 return -ENODEV;
9000 }
9001 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309002
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309003 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9004 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9005 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009006 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309007 "%s: device_mode = %s (%d) freq = %d", __func__,
9008 hdd_device_modetoString(pAdapter->device_mode),
9009 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309010
9011 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9012 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309013 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009014 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309015 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009016 }
9017
9018 /*
9019 * Do freq to chan conversion
9020 * TODO: for 11a
9021 */
9022
9023 channel = ieee80211_frequency_to_channel(freq);
9024
9025 /* Check freq range */
9026 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9027 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9028 {
9029 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009030 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009031 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9032 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9033 return -EINVAL;
9034 }
9035
9036 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9037
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309038 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9039 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009040 {
9041 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9042 {
9043 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009044 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009045 return -EINVAL;
9046 }
9047 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9048 "%s: set channel to [%d] for device mode =%d",
9049 __func__, channel,pAdapter->device_mode);
9050 }
9051 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009052 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009053 )
9054 {
9055 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9056 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9057 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9058
9059 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9060 {
9061 /* Link is up then return cant set channel*/
9062 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009063 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009064 return -EINVAL;
9065 }
9066
9067 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9068 pHddStaCtx->conn_info.operationChannel = channel;
9069 pRoamProfile->ChannelInfo.ChannelList =
9070 &pHddStaCtx->conn_info.operationChannel;
9071 }
9072 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009073 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009074 )
9075 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309076 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9077 {
9078 if(VOS_STATUS_SUCCESS !=
9079 wlan_hdd_validate_operation_channel(pAdapter,channel))
9080 {
9081 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009082 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309083 return -EINVAL;
9084 }
9085 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9086 }
9087 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009088 {
9089 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9090
9091 /* If auto channel selection is configured as enable/ 1 then ignore
9092 channel set by supplicant
9093 */
9094 if ( cfg_param->apAutoChannelSelection )
9095 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309096 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9097 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009098 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309099 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9100 __func__, hdd_device_modetoString(pAdapter->device_mode),
9101 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009102 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309103 else
9104 {
9105 if(VOS_STATUS_SUCCESS !=
9106 wlan_hdd_validate_operation_channel(pAdapter,channel))
9107 {
9108 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009109 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309110 return -EINVAL;
9111 }
9112 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9113 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009114 }
9115 }
9116 else
9117 {
9118 hddLog(VOS_TRACE_LEVEL_FATAL,
9119 "%s: Invalid device mode failed to set valid channel", __func__);
9120 return -EINVAL;
9121 }
9122 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309123 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009124}
9125
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309126static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9127 struct net_device *dev,
9128 struct ieee80211_channel *chan,
9129 enum nl80211_channel_type channel_type
9130 )
9131{
9132 int ret;
9133
9134 vos_ssr_protect(__func__);
9135 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9136 vos_ssr_unprotect(__func__);
9137
9138 return ret;
9139}
9140
Jeff Johnson295189b2012-06-20 16:38:30 -07009141#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9142static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9143 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009144#else
9145static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9146 struct cfg80211_beacon_data *params,
9147 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309148 enum nl80211_hidden_ssid hidden_ssid,
9149 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009150#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009151{
9152 tsap_Config_t *pConfig;
9153 beacon_data_t *pBeacon = NULL;
9154 struct ieee80211_mgmt *pMgmt_frame;
9155 v_U8_t *pIe=NULL;
9156 v_U16_t capab_info;
9157 eCsrAuthType RSNAuthType;
9158 eCsrEncryptionType RSNEncryptType;
9159 eCsrEncryptionType mcRSNEncryptType;
9160 int status = VOS_STATUS_SUCCESS;
9161 tpWLAN_SAPEventCB pSapEventCallback;
9162 hdd_hostapd_state_t *pHostapdState;
9163 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
9164 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309165 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009166 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309167 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009168 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009169 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309170 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009171 v_BOOL_t MFPCapable = VOS_FALSE;
9172 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309173 v_BOOL_t sapEnable11AC =
9174 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07009175 ENTER();
9176
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309177 iniConfig = pHddCtx->cfg_ini;
9178
Jeff Johnson295189b2012-06-20 16:38:30 -07009179 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9180
9181 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9182
9183 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9184
9185 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9186
9187 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9188
9189 //channel is already set in the set_channel Call back
9190 //pConfig->channel = pCommitConfig->channel;
9191
9192 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309193 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009194 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9195
9196 pConfig->dtim_period = pBeacon->dtim_period;
9197
Arif Hussain6d2a3322013-11-17 19:50:10 -08009198 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009199 pConfig->dtim_period);
9200
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009201 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009202 {
9203 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009204 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309205 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9206 {
9207 tANI_BOOLEAN restartNeeded;
9208 pConfig->ieee80211d = 1;
9209 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9210 sme_setRegInfo(hHal, pConfig->countryCode);
9211 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9212 }
9213 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009214 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009215 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009216 pConfig->ieee80211d = 1;
9217 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9218 sme_setRegInfo(hHal, pConfig->countryCode);
9219 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009220 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009221 else
9222 {
9223 pConfig->ieee80211d = 0;
9224 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309225 /*
9226 * If auto channel is configured i.e. channel is 0,
9227 * so skip channel validation.
9228 */
9229 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9230 {
9231 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9232 {
9233 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009234 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309235 return -EINVAL;
9236 }
9237 }
9238 else
9239 {
9240 if(1 != pHddCtx->is_dynamic_channel_range_set)
9241 {
9242 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9243 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9244 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9245 }
9246 pHddCtx->is_dynamic_channel_range_set = 0;
9247 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009248 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009249 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009250 {
9251 pConfig->ieee80211d = 0;
9252 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309253
9254#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9255 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9256 pConfig->authType = eSAP_OPEN_SYSTEM;
9257 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9258 pConfig->authType = eSAP_SHARED_KEY;
9259 else
9260 pConfig->authType = eSAP_AUTO_SWITCH;
9261#else
9262 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9263 pConfig->authType = eSAP_OPEN_SYSTEM;
9264 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9265 pConfig->authType = eSAP_SHARED_KEY;
9266 else
9267 pConfig->authType = eSAP_AUTO_SWITCH;
9268#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009269
9270 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309271
9272 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009273 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
9274
9275 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9276
9277 /*Set wps station to configured*/
9278 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9279
9280 if(pIe)
9281 {
9282 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9283 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009284 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009285 return -EINVAL;
9286 }
9287 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9288 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009289 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009290 /* Check 15 bit of WPS IE as it contain information for wps state
9291 * WPS state
9292 */
9293 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9294 {
9295 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9296 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9297 {
9298 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9299 }
9300 }
9301 }
9302 else
9303 {
9304 pConfig->wps_state = SAP_WPS_DISABLED;
9305 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309306 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009307
c_hpothufe599e92014-06-16 11:38:55 +05309308 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9309 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9310 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9311 eCSR_ENCRYPT_TYPE_NONE;
9312
Jeff Johnson295189b2012-06-20 16:38:30 -07009313 pConfig->RSNWPAReqIELength = 0;
9314 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309315 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009316 WLAN_EID_RSN);
9317 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309318 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009319 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9320 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9321 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309322 /* The actual processing may eventually be more extensive than
9323 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009324 * by the app.
9325 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309326 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009327 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9328 &RSNEncryptType,
9329 &mcRSNEncryptType,
9330 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009331 &MFPCapable,
9332 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009333 pConfig->pRSNWPAReqIE[1]+2,
9334 pConfig->pRSNWPAReqIE );
9335
9336 if( VOS_STATUS_SUCCESS == status )
9337 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309338 /* Now copy over all the security attributes you have
9339 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009340 * */
9341 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9342 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9343 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9344 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309345 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009346 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9348 }
9349 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309350
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9352 pBeacon->tail, pBeacon->tail_len);
9353
9354 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9355 {
9356 if (pConfig->pRSNWPAReqIE)
9357 {
9358 /*Mixed mode WPA/WPA2*/
9359 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
9360 pConfig->RSNWPAReqIELength += pIe[1] + 2;
9361 }
9362 else
9363 {
9364 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9365 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9366 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309367 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009368 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9369 &RSNEncryptType,
9370 &mcRSNEncryptType,
9371 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009372 &MFPCapable,
9373 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 pConfig->pRSNWPAReqIE[1]+2,
9375 pConfig->pRSNWPAReqIE );
9376
9377 if( VOS_STATUS_SUCCESS == status )
9378 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309379 /* Now copy over all the security attributes you have
9380 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009381 * */
9382 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9383 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9384 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9385 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309386 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009387 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009388 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9389 }
9390 }
9391 }
9392
Jeff Johnson4416a782013-03-25 14:17:50 -07009393 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
9394 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9395 return -EINVAL;
9396 }
9397
Jeff Johnson295189b2012-06-20 16:38:30 -07009398 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9399
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009400#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009401 if (params->ssid != NULL)
9402 {
9403 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9404 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9405 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9406 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9407 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009408#else
9409 if (ssid != NULL)
9410 {
9411 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9412 pConfig->SSIDinfo.ssid.length = ssid_len;
9413 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9414 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9415 }
9416#endif
9417
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309418 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009419 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309420
Jeff Johnson295189b2012-06-20 16:38:30 -07009421 /* default value */
9422 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9423 pConfig->num_accept_mac = 0;
9424 pConfig->num_deny_mac = 0;
9425
9426 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9427 pBeacon->tail, pBeacon->tail_len);
9428
9429 /* pIe for black list is following form:
9430 type : 1 byte
9431 length : 1 byte
9432 OUI : 4 bytes
9433 acl type : 1 byte
9434 no of mac addr in black list: 1 byte
9435 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309436 */
9437 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009438 {
9439 pConfig->SapMacaddr_acl = pIe[6];
9440 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009441 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009442 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309443 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9444 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009445 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9446 for (i = 0; i < pConfig->num_deny_mac; i++)
9447 {
9448 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9449 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309450 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009451 }
9452 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9453 pBeacon->tail, pBeacon->tail_len);
9454
9455 /* pIe for white list is following form:
9456 type : 1 byte
9457 length : 1 byte
9458 OUI : 4 bytes
9459 acl type : 1 byte
9460 no of mac addr in white list: 1 byte
9461 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309462 */
9463 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009464 {
9465 pConfig->SapMacaddr_acl = pIe[6];
9466 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009467 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009468 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309469 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9470 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009471 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9472 for (i = 0; i < pConfig->num_accept_mac; i++)
9473 {
9474 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9475 acl_entry++;
9476 }
9477 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309478
Jeff Johnson295189b2012-06-20 16:38:30 -07009479 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9480
Jeff Johnsone7245742012-09-05 17:12:55 -07009481#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009482 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309483 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9484 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309485 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9486 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009487 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9488 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309489 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9490 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009491 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309492 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009493 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309494 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009495
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309496 /* If ACS disable and selected channel <= 14
9497 * OR
9498 * ACS enabled and ACS operating band is choosen as 2.4
9499 * AND
9500 * VHT in 2.4G Disabled
9501 * THEN
9502 * Fallback to 11N mode
9503 */
9504 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9505 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309506 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309507 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009508 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309509 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9510 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009511 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9512 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009513 }
9514#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309515
Jeff Johnson295189b2012-06-20 16:38:30 -07009516 // ht_capab is not what the name conveys,this is used for protection bitmap
9517 pConfig->ht_capab =
9518 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9519
9520 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
9521 {
9522 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9523 return -EINVAL;
9524 }
9525
9526 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309527 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009528 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9529 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309530 pConfig->obssProtEnabled =
9531 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009532
Chet Lanctot8cecea22014-02-11 19:09:36 -08009533#ifdef WLAN_FEATURE_11W
9534 pConfig->mfpCapable = MFPCapable;
9535 pConfig->mfpRequired = MFPRequired;
9536 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9537 pConfig->mfpCapable, pConfig->mfpRequired);
9538#endif
9539
Arif Hussain6d2a3322013-11-17 19:50:10 -08009540 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009541 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009542 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9543 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9544 (int)pConfig->channel);
9545 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9546 pConfig->SapHw_mode, pConfig->privacy,
9547 pConfig->authType);
9548 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9549 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9550 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9551 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009552
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309553 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009554 {
9555 //Bss already started. just return.
9556 //TODO Probably it should update some beacon params.
9557 hddLog( LOGE, "Bss Already started...Ignore the request");
9558 EXIT();
9559 return 0;
9560 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309561
Agarwal Ashish51325b52014-06-16 16:50:49 +05309562 if (vos_max_concurrent_connections_reached()) {
9563 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9564 return -EINVAL;
9565 }
9566
Jeff Johnson295189b2012-06-20 16:38:30 -07009567 pConfig->persona = pHostapdAdapter->device_mode;
9568
Peng Xu2446a892014-09-05 17:21:18 +05309569 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9570 if ( NULL != psmeConfig)
9571 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309572 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309573 sme_GetConfigParam(hHal, psmeConfig);
9574 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309575#ifdef WLAN_FEATURE_AP_HT40_24G
9576 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9577 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9578 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9579 {
9580 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9581 sme_UpdateConfig (hHal, psmeConfig);
9582 }
9583#endif
Peng Xu2446a892014-09-05 17:21:18 +05309584 vos_mem_free(psmeConfig);
9585 }
Peng Xuafc34e32014-09-25 13:23:55 +05309586 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309587
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 pSapEventCallback = hdd_hostapd_SAPEventCB;
9589 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9590 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9591 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009592 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 return -EINVAL;
9594 }
9595
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309596 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009597 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9598
9599 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309600
Jeff Johnson295189b2012-06-20 16:38:30 -07009601 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309602 {
9603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009604 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009605 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009606 VOS_ASSERT(0);
9607 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309608
Jeff Johnson295189b2012-06-20 16:38:30 -07009609 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309610 /* Initialize WMM configuation */
9611 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309612 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009613
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009614#ifdef WLAN_FEATURE_P2P_DEBUG
9615 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9616 {
9617 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9618 {
9619 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9620 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009621 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009622 }
9623 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9624 {
9625 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9626 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009627 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009628 }
9629 }
9630#endif
9631
Jeff Johnson295189b2012-06-20 16:38:30 -07009632 pHostapdState->bCommit = TRUE;
9633 EXIT();
9634
9635 return 0;
9636}
9637
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009638#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309639static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309640 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009641 struct beacon_parameters *params)
9642{
9643 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309644 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309645 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009646
9647 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309648
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309649 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9650 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9651 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309652 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9653 hdd_device_modetoString(pAdapter->device_mode),
9654 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009655
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309656 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9657 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309658 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009659 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309660 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009661 }
9662
Agarwal Ashish51325b52014-06-16 16:50:49 +05309663 if (vos_max_concurrent_connections_reached()) {
9664 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9665 return -EINVAL;
9666 }
9667
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309668 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009669 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009670 )
9671 {
9672 beacon_data_t *old,*new;
9673
9674 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309675
Jeff Johnson295189b2012-06-20 16:38:30 -07009676 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309677 {
9678 hddLog(VOS_TRACE_LEVEL_WARN,
9679 FL("already beacon info added to session(%d)"),
9680 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009681 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309682 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009683
9684 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9685
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309686 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009687 {
9688 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009689 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009690 return -EINVAL;
9691 }
9692
9693 pAdapter->sessionCtx.ap.beacon = new;
9694
9695 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9696 }
9697
9698 EXIT();
9699 return status;
9700}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309701
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309702static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9703 struct net_device *dev,
9704 struct beacon_parameters *params)
9705{
9706 int ret;
9707
9708 vos_ssr_protect(__func__);
9709 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
9710 vos_ssr_unprotect(__func__);
9711
9712 return ret;
9713}
9714
9715static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009716 struct net_device *dev,
9717 struct beacon_parameters *params)
9718{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309720 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9721 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309722 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009723
9724 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309725
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309726 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9727 TRACE_CODE_HDD_CFG80211_SET_BEACON,
9728 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
9729 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9730 __func__, hdd_device_modetoString(pAdapter->device_mode),
9731 pAdapter->device_mode);
9732
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309733 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9734 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309735 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009736 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309737 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009738 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309739
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309740 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009741 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309742 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009743 {
9744 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309745
Jeff Johnson295189b2012-06-20 16:38:30 -07009746 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309747
Jeff Johnson295189b2012-06-20 16:38:30 -07009748 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309749 {
9750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9751 FL("session(%d) old and new heads points to NULL"),
9752 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009753 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309754 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009755
9756 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9757
9758 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309759 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009760 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009761 return -EINVAL;
9762 }
9763
9764 pAdapter->sessionCtx.ap.beacon = new;
9765
9766 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9767 }
9768
9769 EXIT();
9770 return status;
9771}
9772
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309773static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
9774 struct net_device *dev,
9775 struct beacon_parameters *params)
9776{
9777 int ret;
9778
9779 vos_ssr_protect(__func__);
9780 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
9781 vos_ssr_unprotect(__func__);
9782
9783 return ret;
9784}
9785
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009786#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9787
9788#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309789static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009790 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009791#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309792static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009793 struct net_device *dev)
9794#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009795{
9796 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07009797 hdd_context_t *pHddCtx = NULL;
9798 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309799 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309800 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009801
9802 ENTER();
9803
9804 if (NULL == pAdapter)
9805 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009807 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009808 return -ENODEV;
9809 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009810
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309811 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9812 TRACE_CODE_HDD_CFG80211_STOP_AP,
9813 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309814 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9815 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309816 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009817 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309818 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07009819 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009820
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009821 pScanInfo = &pHddCtx->scan_info;
9822
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309823 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9824 __func__, hdd_device_modetoString(pAdapter->device_mode),
9825 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009826
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309827 ret = wlan_hdd_scan_abort(pAdapter);
9828
Girish Gowli4bf7a632014-06-12 13:42:11 +05309829 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07009830 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9832 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309833
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309834 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07009835 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9837 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08009838
Jeff Johnsone7245742012-09-05 17:12:55 -07009839 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309840 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07009841 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309842 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009843 }
9844
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05309845 /* Delete all associated STAs before stopping AP/P2P GO */
9846 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05309847 hdd_hostapd_stop(dev);
9848
Jeff Johnson295189b2012-06-20 16:38:30 -07009849 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009850 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009851 )
9852 {
9853 beacon_data_t *old;
9854
9855 old = pAdapter->sessionCtx.ap.beacon;
9856
9857 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309858 {
9859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9860 FL("session(%d) beacon data points to NULL"),
9861 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009862 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309863 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009864
Jeff Johnson295189b2012-06-20 16:38:30 -07009865 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009866
9867 mutex_lock(&pHddCtx->sap_lock);
9868 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9869 {
Jeff Johnson4416a782013-03-25 14:17:50 -07009870 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 {
9872 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9873
9874 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9875
9876 if (!VOS_IS_STATUS_SUCCESS(status))
9877 {
9878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009879 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009880 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309881 }
9882 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009883 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309884 /* BSS stopped, clear the active sessions for this device mode */
9885 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009886 }
9887 mutex_unlock(&pHddCtx->sap_lock);
9888
9889 if(status != VOS_STATUS_SUCCESS)
9890 {
9891 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009892 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009893 return -EINVAL;
9894 }
9895
Jeff Johnson4416a782013-03-25 14:17:50 -07009896 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009897 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
9898 ==eHAL_STATUS_FAILURE)
9899 {
9900 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009901 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009902 }
9903
Jeff Johnson4416a782013-03-25 14:17:50 -07009904 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009905 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9906 eANI_BOOLEAN_FALSE) )
9907 {
9908 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009909 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 }
9911
9912 // Reset WNI_CFG_PROBE_RSP Flags
9913 wlan_hdd_reset_prob_rspies(pAdapter);
9914
9915 pAdapter->sessionCtx.ap.beacon = NULL;
9916 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009917#ifdef WLAN_FEATURE_P2P_DEBUG
9918 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
9919 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
9920 {
9921 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
9922 "GO got removed");
9923 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
9924 }
9925#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009926 }
9927 EXIT();
9928 return status;
9929}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009930
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309931#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9932static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
9933 struct net_device *dev)
9934{
9935 int ret;
9936
9937 vos_ssr_protect(__func__);
9938 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
9939 vos_ssr_unprotect(__func__);
9940
9941 return ret;
9942}
9943#else
9944static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
9945 struct net_device *dev)
9946{
9947 int ret;
9948
9949 vos_ssr_protect(__func__);
9950 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
9951 vos_ssr_unprotect(__func__);
9952
9953 return ret;
9954}
9955#endif
9956
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009957#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
9958
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309959static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309960 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009961 struct cfg80211_ap_settings *params)
9962{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309963 hdd_adapter_t *pAdapter;
9964 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309965 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009966
9967 ENTER();
9968
Girish Gowlib143d7a2015-02-18 19:39:55 +05309969 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009970 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05309972 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309973 return -ENODEV;
9974 }
9975
9976 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9977 if (NULL == pAdapter)
9978 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309980 "%s: HDD adapter is Null", __func__);
9981 return -ENODEV;
9982 }
9983
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309984 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9985 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
9986 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309987 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9988 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309990 "%s: HDD adapter magic is invalid", __func__);
9991 return -ENODEV;
9992 }
9993
9994 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309995 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309996 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309997 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309998 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309999 }
10000
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010001 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10002 __func__, hdd_device_modetoString(pAdapter->device_mode),
10003 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010004
10005 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010006 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010007 )
10008 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010009 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010010
10011 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010012
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010013 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010014 {
10015 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10016 FL("already beacon info added to session(%d)"),
10017 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010018 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010019 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010020
Girish Gowlib143d7a2015-02-18 19:39:55 +053010021#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10022 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10023 &new,
10024 &params->beacon);
10025#else
10026 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10027 &new,
10028 &params->beacon,
10029 params->dtim_period);
10030#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010031
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010032 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010033 {
10034 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010035 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010036 return -EINVAL;
10037 }
10038 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010039#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010040 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10041#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10042 params->channel, params->channel_type);
10043#else
10044 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10045#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010046#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010047 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010048 params->ssid_len, params->hidden_ssid,
10049 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010050 }
10051
10052 EXIT();
10053 return status;
10054}
10055
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010056static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10057 struct net_device *dev,
10058 struct cfg80211_ap_settings *params)
10059{
10060 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010061
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010062 vos_ssr_protect(__func__);
10063 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10064 vos_ssr_unprotect(__func__);
10065
10066 return ret;
10067}
10068
10069static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010070 struct net_device *dev,
10071 struct cfg80211_beacon_data *params)
10072{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010073 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010074 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010075 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010076
10077 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010078
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010079 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10080 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10081 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010082 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010083 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010084
10085 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10086 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010087 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010088 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010089 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010090 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010091
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010092 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010093 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010094 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010095 {
10096 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010097
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010098 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010099
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010100 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010101 {
10102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10103 FL("session(%d) beacon data points to NULL"),
10104 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010105 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010106 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010107
10108 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10109
10110 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010111 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010112 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010113 return -EINVAL;
10114 }
10115
10116 pAdapter->sessionCtx.ap.beacon = new;
10117
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010118 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10119 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010120 }
10121
10122 EXIT();
10123 return status;
10124}
10125
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010126static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10127 struct net_device *dev,
10128 struct cfg80211_beacon_data *params)
10129{
10130 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010131
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010132 vos_ssr_protect(__func__);
10133 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10134 vos_ssr_unprotect(__func__);
10135
10136 return ret;
10137}
10138
10139#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010140
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010141static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010142 struct net_device *dev,
10143 struct bss_parameters *params)
10144{
10145 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010146 hdd_context_t *pHddCtx;
10147 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010148
10149 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010150
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010151 if (NULL == pAdapter)
10152 {
10153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10154 "%s: HDD adapter is Null", __func__);
10155 return -ENODEV;
10156 }
10157 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010158 ret = wlan_hdd_validate_context(pHddCtx);
10159 if (0 != ret)
10160 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010161 return ret;
10162 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010163 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10164 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10165 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010166 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10167 __func__, hdd_device_modetoString(pAdapter->device_mode),
10168 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010169
10170 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010171 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010172 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010173 {
10174 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10175 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010176 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010177 {
10178 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010179 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010180 }
10181
10182 EXIT();
10183 return 0;
10184}
10185
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010186static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10187 struct net_device *dev,
10188 struct bss_parameters *params)
10189{
10190 int ret;
10191
10192 vos_ssr_protect(__func__);
10193 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10194 vos_ssr_unprotect(__func__);
10195
10196 return ret;
10197}
Kiet Lam10841362013-11-01 11:36:50 +053010198/* FUNCTION: wlan_hdd_change_country_code_cd
10199* to wait for contry code completion
10200*/
10201void* wlan_hdd_change_country_code_cb(void *pAdapter)
10202{
10203 hdd_adapter_t *call_back_pAdapter = pAdapter;
10204 complete(&call_back_pAdapter->change_country_code);
10205 return NULL;
10206}
10207
Jeff Johnson295189b2012-06-20 16:38:30 -070010208/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010209 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010210 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10211 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010212int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010213 struct net_device *ndev,
10214 enum nl80211_iftype type,
10215 u32 *flags,
10216 struct vif_params *params
10217 )
10218{
10219 struct wireless_dev *wdev;
10220 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010221 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010222 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010223 tCsrRoamProfile *pRoamProfile = NULL;
10224 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010225 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010226 eMib_dot11DesiredBssType connectedBssType;
10227 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010228 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010229
10230 ENTER();
10231
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010232 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010233 {
10234 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10235 "%s: Adapter context is null", __func__);
10236 return VOS_STATUS_E_FAILURE;
10237 }
10238
10239 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10240 if (!pHddCtx)
10241 {
10242 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10243 "%s: HDD context is null", __func__);
10244 return VOS_STATUS_E_FAILURE;
10245 }
10246
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010247 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10248 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10249 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010250 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010251 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010252 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010253 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010254 }
10255
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010256 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10257 __func__, hdd_device_modetoString(pAdapter->device_mode),
10258 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010259
Agarwal Ashish51325b52014-06-16 16:50:49 +053010260 if (vos_max_concurrent_connections_reached()) {
10261 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10262 return -EINVAL;
10263 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010264 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010265 wdev = ndev->ieee80211_ptr;
10266
10267#ifdef WLAN_BTAMP_FEATURE
10268 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10269 (NL80211_IFTYPE_ADHOC == type)||
10270 (NL80211_IFTYPE_AP == type)||
10271 (NL80211_IFTYPE_P2P_GO == type))
10272 {
10273 pHddCtx->isAmpAllowed = VOS_FALSE;
10274 // stop AMP traffic
10275 status = WLANBAP_StopAmp();
10276 if(VOS_STATUS_SUCCESS != status )
10277 {
10278 pHddCtx->isAmpAllowed = VOS_TRUE;
10279 hddLog(VOS_TRACE_LEVEL_FATAL,
10280 "%s: Failed to stop AMP", __func__);
10281 return -EINVAL;
10282 }
10283 }
10284#endif //WLAN_BTAMP_FEATURE
10285 /* Reset the current device mode bit mask*/
10286 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10287
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010288 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10289 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10290 (type == NL80211_IFTYPE_P2P_GO)))
10291 {
10292 /* Notify Mode change in case of concurrency.
10293 * Below function invokes TDLS teardown Functionality Since TDLS is
10294 * not Supported in case of concurrency i.e Once P2P session
10295 * is detected disable offchannel and teardown TDLS links
10296 */
10297 hddLog(LOG1,
10298 FL("Device mode = %d Interface type = %d"),
10299 pAdapter->device_mode, type);
10300 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10301 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010302
Jeff Johnson295189b2012-06-20 16:38:30 -070010303 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010304 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010305 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010306 )
10307 {
10308 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010309 if (!pWextState)
10310 {
10311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10312 "%s: pWextState is null", __func__);
10313 return VOS_STATUS_E_FAILURE;
10314 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010315 pRoamProfile = &pWextState->roamProfile;
10316 LastBSSType = pRoamProfile->BSSType;
10317
10318 switch (type)
10319 {
10320 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010321 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010322 hddLog(VOS_TRACE_LEVEL_INFO,
10323 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10324 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010325#ifdef WLAN_FEATURE_11AC
10326 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10327 {
10328 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10329 }
10330#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010331 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010332 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010333 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010334 //Check for sub-string p2p to confirm its a p2p interface
10335 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010336 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010337#ifdef FEATURE_WLAN_TDLS
10338 mutex_lock(&pHddCtx->tdls_lock);
10339 wlan_hdd_tdls_exit(pAdapter, TRUE);
10340 mutex_unlock(&pHddCtx->tdls_lock);
10341#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010342 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10343 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10344 }
10345 else
10346 {
10347 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010348 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010349 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010350 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010351
Jeff Johnson295189b2012-06-20 16:38:30 -070010352 case NL80211_IFTYPE_ADHOC:
10353 hddLog(VOS_TRACE_LEVEL_INFO,
10354 "%s: setting interface Type to ADHOC", __func__);
10355 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10356 pRoamProfile->phyMode =
10357 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010358 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010359 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010360 hdd_set_ibss_ops( pAdapter );
10361 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010362
10363 status = hdd_sta_id_hash_attach(pAdapter);
10364 if (VOS_STATUS_SUCCESS != status) {
10365 hddLog(VOS_TRACE_LEVEL_ERROR,
10366 FL("Failed to initialize hash for IBSS"));
10367 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010368 break;
10369
10370 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010371 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010372 {
10373 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10374 "%s: setting interface Type to %s", __func__,
10375 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10376
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010377 //Cancel any remain on channel for GO mode
10378 if (NL80211_IFTYPE_P2P_GO == type)
10379 {
10380 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10381 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010382 if (NL80211_IFTYPE_AP == type)
10383 {
10384 /* As Loading WLAN Driver one interface being created for p2p device
10385 * address. This will take one HW STA and the max number of clients
10386 * that can connect to softAP will be reduced by one. so while changing
10387 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10388 * interface as it is not required in SoftAP mode.
10389 */
10390
10391 // Get P2P Adapter
10392 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10393
10394 if (pP2pAdapter)
10395 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010396 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010397 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010398 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10399 }
10400 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010401 //Disable IMPS & BMPS for SAP/GO
10402 if(VOS_STATUS_E_FAILURE ==
10403 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10404 {
10405 //Fail to Exit BMPS
10406 VOS_ASSERT(0);
10407 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010408
10409 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10410
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010411#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010412
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010413 /* A Mutex Lock is introduced while changing the mode to
10414 * protect the concurrent access for the Adapters by TDLS
10415 * module.
10416 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010417 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010418#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010419 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010420 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010421 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010422 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10423 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010424#ifdef FEATURE_WLAN_TDLS
10425 mutex_unlock(&pHddCtx->tdls_lock);
10426#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010427 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10428 (pConfig->apRandomBssidEnabled))
10429 {
10430 /* To meet Android requirements create a randomized
10431 MAC address of the form 02:1A:11:Fx:xx:xx */
10432 get_random_bytes(&ndev->dev_addr[3], 3);
10433 ndev->dev_addr[0] = 0x02;
10434 ndev->dev_addr[1] = 0x1A;
10435 ndev->dev_addr[2] = 0x11;
10436 ndev->dev_addr[3] |= 0xF0;
10437 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10438 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010439 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10440 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010441 }
10442
Jeff Johnson295189b2012-06-20 16:38:30 -070010443 hdd_set_ap_ops( pAdapter->dev );
10444
Kiet Lam10841362013-11-01 11:36:50 +053010445 /* This is for only SAP mode where users can
10446 * control country through ini.
10447 * P2P GO follows station country code
10448 * acquired during the STA scanning. */
10449 if((NL80211_IFTYPE_AP == type) &&
10450 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10451 {
10452 int status = 0;
10453 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10454 "%s: setting country code from INI ", __func__);
10455 init_completion(&pAdapter->change_country_code);
10456 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10457 (void *)(tSmeChangeCountryCallback)
10458 wlan_hdd_change_country_code_cb,
10459 pConfig->apCntryCode, pAdapter,
10460 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010461 eSIR_FALSE,
10462 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010463 if (eHAL_STATUS_SUCCESS == status)
10464 {
10465 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010466 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010467 &pAdapter->change_country_code,
10468 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010469 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010470 {
10471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010472 FL("SME Timed out while setting country code %ld"),
10473 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010474
10475 if (pHddCtx->isLogpInProgress)
10476 {
10477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10478 "%s: LOGP in Progress. Ignore!!!", __func__);
10479 return -EAGAIN;
10480 }
Kiet Lam10841362013-11-01 11:36:50 +053010481 }
10482 }
10483 else
10484 {
10485 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010486 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010487 return -EINVAL;
10488 }
10489 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010490 status = hdd_init_ap_mode(pAdapter);
10491 if(status != VOS_STATUS_SUCCESS)
10492 {
10493 hddLog(VOS_TRACE_LEVEL_FATAL,
10494 "%s: Error initializing the ap mode", __func__);
10495 return -EINVAL;
10496 }
10497 hdd_set_conparam(1);
10498
Nirav Shah7e3c8132015-06-22 23:51:42 +053010499 status = hdd_sta_id_hash_attach(pAdapter);
10500 if (VOS_STATUS_SUCCESS != status)
10501 {
10502 hddLog(VOS_TRACE_LEVEL_ERROR,
10503 FL("Failed to initialize hash for AP"));
10504 return -EINVAL;
10505 }
10506
Jeff Johnson295189b2012-06-20 16:38:30 -070010507 /*interface type changed update in wiphy structure*/
10508 if(wdev)
10509 {
10510 wdev->iftype = type;
10511 pHddCtx->change_iface = type;
10512 }
10513 else
10514 {
10515 hddLog(VOS_TRACE_LEVEL_ERROR,
10516 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10517 return -EINVAL;
10518 }
10519 goto done;
10520 }
10521
10522 default:
10523 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10524 __func__);
10525 return -EOPNOTSUPP;
10526 }
10527 }
10528 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010529 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010530 )
10531 {
10532 switch(type)
10533 {
10534 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010535 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010536 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010537
10538 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010539#ifdef FEATURE_WLAN_TDLS
10540
10541 /* A Mutex Lock is introduced while changing the mode to
10542 * protect the concurrent access for the Adapters by TDLS
10543 * module.
10544 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010545 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010546#endif
c_hpothu002231a2015-02-05 14:58:51 +053010547 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010548 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010549 //Check for sub-string p2p to confirm its a p2p interface
10550 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010551 {
10552 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10553 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10554 }
10555 else
10556 {
10557 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010558 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010559 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010560 hdd_set_conparam(0);
10561 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010562 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10563 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010564#ifdef FEATURE_WLAN_TDLS
10565 mutex_unlock(&pHddCtx->tdls_lock);
10566#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010567 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010568 if( VOS_STATUS_SUCCESS != status )
10569 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010570 /* In case of JB, for P2P-GO, only change interface will be called,
10571 * This is the right place to enable back bmps_imps()
10572 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010573 if (pHddCtx->hdd_wlan_suspended)
10574 {
10575 hdd_set_pwrparams(pHddCtx);
10576 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010577 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010578 goto done;
10579 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010580 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010581 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010582 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10583 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010584 goto done;
10585 default:
10586 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10587 __func__);
10588 return -EOPNOTSUPP;
10589
10590 }
10591
10592 }
10593 else
10594 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010595 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10596 __func__, hdd_device_modetoString(pAdapter->device_mode),
10597 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010598 return -EOPNOTSUPP;
10599 }
10600
10601
10602 if(pRoamProfile)
10603 {
10604 if ( LastBSSType != pRoamProfile->BSSType )
10605 {
10606 /*interface type changed update in wiphy structure*/
10607 wdev->iftype = type;
10608
10609 /*the BSS mode changed, We need to issue disconnect
10610 if connected or in IBSS disconnect state*/
10611 if ( hdd_connGetConnectedBssType(
10612 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10613 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10614 {
10615 /*need to issue a disconnect to CSR.*/
10616 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10617 if( eHAL_STATUS_SUCCESS ==
10618 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10619 pAdapter->sessionId,
10620 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10621 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010622 ret = wait_for_completion_interruptible_timeout(
10623 &pAdapter->disconnect_comp_var,
10624 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10625 if (ret <= 0)
10626 {
10627 hddLog(VOS_TRACE_LEVEL_ERROR,
10628 FL("wait on disconnect_comp_var failed %ld"), ret);
10629 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010630 }
10631 }
10632 }
10633 }
10634
10635done:
10636 /*set bitmask based on updated value*/
10637 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010638
10639 /* Only STA mode support TM now
10640 * all other mode, TM feature should be disabled */
10641 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10642 (~VOS_STA & pHddCtx->concurrency_mode) )
10643 {
10644 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10645 }
10646
Jeff Johnson295189b2012-06-20 16:38:30 -070010647#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010648 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010649 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010650 {
10651 //we are ok to do AMP
10652 pHddCtx->isAmpAllowed = VOS_TRUE;
10653 }
10654#endif //WLAN_BTAMP_FEATURE
10655 EXIT();
10656 return 0;
10657}
10658
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010659/*
10660 * FUNCTION: wlan_hdd_cfg80211_change_iface
10661 * wrapper function to protect the actual implementation from SSR.
10662 */
10663int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10664 struct net_device *ndev,
10665 enum nl80211_iftype type,
10666 u32 *flags,
10667 struct vif_params *params
10668 )
10669{
10670 int ret;
10671
10672 vos_ssr_protect(__func__);
10673 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10674 vos_ssr_unprotect(__func__);
10675
10676 return ret;
10677}
10678
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010679#ifdef FEATURE_WLAN_TDLS
10680static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010681 struct net_device *dev,
10682#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10683 const u8 *mac,
10684#else
10685 u8 *mac,
10686#endif
10687 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010688{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010689 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010690 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010691 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010692 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010693 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010694 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010695
10696 ENTER();
10697
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010698 if (!dev) {
10699 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10700 return -EINVAL;
10701 }
10702
10703 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10704 if (!pAdapter) {
10705 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
10706 return -EINVAL;
10707 }
10708
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010709 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010710 {
10711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10712 "Invalid arguments");
10713 return -EINVAL;
10714 }
Hoonki Lee27511902013-03-14 18:19:06 -070010715
10716 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
10717 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
10718 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070010720 "%s: TDLS mode is disabled OR not enabled in FW."
10721 MAC_ADDRESS_STR " Request declined.",
10722 __func__, MAC_ADDR_ARRAY(mac));
10723 return -ENOTSUPP;
10724 }
10725
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010726 if (pHddCtx->isLogpInProgress)
10727 {
10728 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10729 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053010730 wlan_hdd_tdls_set_link_status(pAdapter,
10731 mac,
10732 eTDLS_LINK_IDLE,
10733 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010734 return -EBUSY;
10735 }
10736
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010737 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053010738 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010739
10740 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010742 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
10743 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010744 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010745 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010746 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010747
10748 /* in add station, we accept existing valid staId if there is */
10749 if ((0 == update) &&
10750 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
10751 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010752 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010754 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010755 " link_status %d. staId %d. add station ignored.",
10756 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010757 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010758 return 0;
10759 }
10760 /* in change station, we accept only when staId is valid */
10761 if ((1 == update) &&
10762 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
10763 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
10764 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010765 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010767 "%s: " MAC_ADDRESS_STR
10768 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010769 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
10770 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
10771 mutex_unlock(&pHddCtx->tdls_lock);
10772 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010773 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010774 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010775
10776 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053010777 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010778 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10780 "%s: " MAC_ADDRESS_STR
10781 " TDLS setup is ongoing. Request declined.",
10782 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070010783 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010784 }
10785
10786 /* first to check if we reached to maximum supported TDLS peer.
10787 TODO: for now, return -EPERM looks working fine,
10788 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010789 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
10790 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010791 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010792 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10793 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010794 " TDLS Max peer already connected. Request declined."
10795 " Num of peers (%d), Max allowed (%d).",
10796 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
10797 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010798 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010799 }
10800 else
10801 {
10802 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010803 mutex_lock(&pHddCtx->tdls_lock);
10804 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010805 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010806 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010807 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10809 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
10810 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010811 return -EPERM;
10812 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010813 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010814 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010815 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053010816 wlan_hdd_tdls_set_link_status(pAdapter,
10817 mac,
10818 eTDLS_LINK_CONNECTING,
10819 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010820
Jeff Johnsond75fe012013-04-06 10:53:06 -070010821 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010822 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010823 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010825 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010826 if(StaParams->htcap_present)
10827 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010828 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010829 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010830 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010831 "ht_capa->extended_capabilities: %0x",
10832 StaParams->HTCap.extendedHtCapInfo);
10833 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010834 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010835 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010837 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010838 if(StaParams->vhtcap_present)
10839 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010840 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010841 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
10842 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
10843 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
10844 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010845 {
10846 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010848 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010850 "[%d]: %x ", i, StaParams->supported_rates[i]);
10851 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070010852 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010853 else if ((1 == update) && (NULL == StaParams))
10854 {
10855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10856 "%s : update is true, but staParams is NULL. Error!", __func__);
10857 return -EPERM;
10858 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010859
10860 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
10861
10862 if (!update)
10863 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010864 /*Before adding sta make sure that device exited from BMPS*/
10865 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
10866 {
10867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10868 "%s: Adding tdls peer sta. Disable BMPS", __func__);
10869 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10870 if (status != VOS_STATUS_SUCCESS) {
10871 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
10872 }
10873 }
10874
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010875 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010876 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010877 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010878 hddLog(VOS_TRACE_LEVEL_ERROR,
10879 FL("Failed to add TDLS peer STA. Enable Bmps"));
10880 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010881 return -EPERM;
10882 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010883 }
10884 else
10885 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010886 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010887 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010888 if (ret != eHAL_STATUS_SUCCESS) {
10889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
10890 return -EPERM;
10891 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010892 }
10893
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010894 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010895 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
10896
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053010897 mutex_lock(&pHddCtx->tdls_lock);
10898 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
10899
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010900 if ((pTdlsPeer != NULL) &&
10901 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010902 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010903 hddLog(VOS_TRACE_LEVEL_ERROR,
10904 FL("peer link status %u"), pTdlsPeer->link_status);
10905 mutex_unlock(&pHddCtx->tdls_lock);
10906 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010907 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053010908 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010909
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010910 if (ret <= 0)
10911 {
10912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10913 "%s: timeout waiting for tdls add station indication %ld",
10914 __func__, ret);
10915 goto error;
10916 }
10917
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010918 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
10919 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010921 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010922 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010923 }
10924
10925 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070010926
10927error:
Atul Mittal115287b2014-07-08 13:26:33 +053010928 wlan_hdd_tdls_set_link_status(pAdapter,
10929 mac,
10930 eTDLS_LINK_IDLE,
10931 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010932 return -EPERM;
10933
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010934}
10935#endif
10936
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010937static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010938 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010939#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10940 const u8 *mac,
10941#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010942 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010943#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010944 struct station_parameters *params)
10945{
10946 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010947 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010948 hdd_context_t *pHddCtx;
10949 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010950 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010951 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010952#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010953 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010954 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010955 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053010956 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010957#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010958
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010959 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010960
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010961 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010962 if ((NULL == pAdapter))
10963 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010964 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010965 "invalid adapter ");
10966 return -EINVAL;
10967 }
10968
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010969 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10970 TRACE_CODE_HDD_CHANGE_STATION,
10971 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053010972 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010973
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010974 ret = wlan_hdd_validate_context(pHddCtx);
10975 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053010976 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010977 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010978 }
10979
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010980 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10981
10982 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010983 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10985 "invalid HDD station context");
10986 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010987 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010988 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
10989
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010990 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10991 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070010992 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010993 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070010994 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010995 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070010996 WLANTL_STA_AUTHENTICATED);
10997
Gopichand Nakkala29149562013-05-10 21:43:41 +053010998 if (status != VOS_STATUS_SUCCESS)
10999 {
11000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11001 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11002 return -EINVAL;
11003 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011004 }
11005 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011006 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11007 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011008#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011009 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11010 StaParams.capability = params->capability;
11011 StaParams.uapsd_queues = params->uapsd_queues;
11012 StaParams.max_sp = params->max_sp;
11013
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011014 /* Convert (first channel , number of channels) tuple to
11015 * the total list of channels. This goes with the assumption
11016 * that if the first channel is < 14, then the next channels
11017 * are an incremental of 1 else an incremental of 4 till the number
11018 * of channels.
11019 */
11020 if (0 != params->supported_channels_len) {
11021 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11022 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11023 {
11024 int wifi_chan_index;
11025 StaParams.supported_channels[j] = params->supported_channels[i];
11026 wifi_chan_index =
11027 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11028 no_of_channels = params->supported_channels[i+1];
11029 for(k=1; k <= no_of_channels; k++)
11030 {
11031 StaParams.supported_channels[j+1] =
11032 StaParams.supported_channels[j] + wifi_chan_index;
11033 j+=1;
11034 }
11035 }
11036 StaParams.supported_channels_len = j;
11037 }
11038 vos_mem_copy(StaParams.supported_oper_classes,
11039 params->supported_oper_classes,
11040 params->supported_oper_classes_len);
11041 StaParams.supported_oper_classes_len =
11042 params->supported_oper_classes_len;
11043
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011044 if (0 != params->ext_capab_len)
11045 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
11046 sizeof(StaParams.extn_capability));
11047
11048 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011049 {
11050 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011051 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011052 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011053
11054 StaParams.supported_rates_len = params->supported_rates_len;
11055
11056 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11057 * The supported_rates array , for all the structures propogating till Add Sta
11058 * to the firmware has to be modified , if the supplicant (ieee80211) is
11059 * modified to send more rates.
11060 */
11061
11062 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11063 */
11064 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11065 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11066
11067 if (0 != StaParams.supported_rates_len) {
11068 int i = 0;
11069 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11070 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011072 "Supported Rates with Length %d", StaParams.supported_rates_len);
11073 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011075 "[%d]: %0x", i, StaParams.supported_rates[i]);
11076 }
11077
11078 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011079 {
11080 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011081 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011082 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011083
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011084 if (0 != params->ext_capab_len ) {
11085 /*Define A Macro : TODO Sunil*/
11086 if ((1<<4) & StaParams.extn_capability[3]) {
11087 isBufSta = 1;
11088 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011089 /* TDLS Channel Switching Support */
11090 if ((1<<6) & StaParams.extn_capability[3]) {
11091 isOffChannelSupported = 1;
11092 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011093 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011094
11095 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011096 (params->ht_capa || params->vht_capa ||
11097 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011098 /* TDLS Peer is WME/QoS capable */
11099 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011100
11101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11102 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11103 __func__, isQosWmmSta, StaParams.htcap_present);
11104
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011105 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11106 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011107 isOffChannelSupported,
11108 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011109
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011110 if (VOS_STATUS_SUCCESS != status) {
11111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11112 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11113 return -EINVAL;
11114 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011115 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11116
11117 if (VOS_STATUS_SUCCESS != status) {
11118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11119 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11120 return -EINVAL;
11121 }
11122 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011123#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011124 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011125 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011126 return status;
11127}
11128
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011129#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11130static int wlan_hdd_change_station(struct wiphy *wiphy,
11131 struct net_device *dev,
11132 const u8 *mac,
11133 struct station_parameters *params)
11134#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011135static int wlan_hdd_change_station(struct wiphy *wiphy,
11136 struct net_device *dev,
11137 u8 *mac,
11138 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011139#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011140{
11141 int ret;
11142
11143 vos_ssr_protect(__func__);
11144 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11145 vos_ssr_unprotect(__func__);
11146
11147 return ret;
11148}
11149
Jeff Johnson295189b2012-06-20 16:38:30 -070011150/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011151 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011152 * This function is used to initialize the key information
11153 */
11154#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011155static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011156 struct net_device *ndev,
11157 u8 key_index, bool pairwise,
11158 const u8 *mac_addr,
11159 struct key_params *params
11160 )
11161#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011162static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011163 struct net_device *ndev,
11164 u8 key_index, const u8 *mac_addr,
11165 struct key_params *params
11166 )
11167#endif
11168{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011169 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011170 tCsrRoamSetKey setKey;
11171 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011172 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011173 v_U32_t roamId= 0xFF;
11174 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011175 hdd_hostapd_state_t *pHostapdState;
11176 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011177 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011178 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011179
11180 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011181
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011182 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11183 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11184 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011185 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11186 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011187 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011188 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011189 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011190 }
11191
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011192 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11193 __func__, hdd_device_modetoString(pAdapter->device_mode),
11194 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011195
11196 if (CSR_MAX_NUM_KEY <= key_index)
11197 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011198 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011199 key_index);
11200
11201 return -EINVAL;
11202 }
11203
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011204 if (CSR_MAX_KEY_LEN < params->key_len)
11205 {
11206 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11207 params->key_len);
11208
11209 return -EINVAL;
11210 }
11211
11212 hddLog(VOS_TRACE_LEVEL_INFO,
11213 "%s: called with key index = %d & key length %d",
11214 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011215
11216 /*extract key idx, key len and key*/
11217 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11218 setKey.keyId = key_index;
11219 setKey.keyLength = params->key_len;
11220 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11221
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011222 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011223 {
11224 case WLAN_CIPHER_SUITE_WEP40:
11225 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11226 break;
11227
11228 case WLAN_CIPHER_SUITE_WEP104:
11229 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11230 break;
11231
11232 case WLAN_CIPHER_SUITE_TKIP:
11233 {
11234 u8 *pKey = &setKey.Key[0];
11235 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11236
11237 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11238
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011239 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011240
11241 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011242 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011243 |--------------|----------|----------|
11244 <---16bytes---><--8bytes--><--8bytes-->
11245
11246 */
11247 /*Sme expects the 32 bytes key to be in the below order
11248
11249 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011250 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011251 |--------------|----------|----------|
11252 <---16bytes---><--8bytes--><--8bytes-->
11253 */
11254 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011255 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011256
11257 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011258 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011259
11260 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011261 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011262
11263
11264 break;
11265 }
11266
11267 case WLAN_CIPHER_SUITE_CCMP:
11268 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11269 break;
11270
11271#ifdef FEATURE_WLAN_WAPI
11272 case WLAN_CIPHER_SUITE_SMS4:
11273 {
11274 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11275 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11276 params->key, params->key_len);
11277 return 0;
11278 }
11279#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011280
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011281#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011282 case WLAN_CIPHER_SUITE_KRK:
11283 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11284 break;
11285#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011286
11287#ifdef WLAN_FEATURE_11W
11288 case WLAN_CIPHER_SUITE_AES_CMAC:
11289 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011290 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011291#endif
11292
Jeff Johnson295189b2012-06-20 16:38:30 -070011293 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011294 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011295 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011296 status = -EOPNOTSUPP;
11297 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011298 }
11299
11300 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11301 __func__, setKey.encType);
11302
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011303 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011304#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11305 (!pairwise)
11306#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011307 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011308#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011309 )
11310 {
11311 /* set group key*/
11312 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11313 "%s- %d: setting Broadcast key",
11314 __func__, __LINE__);
11315 setKey.keyDirection = eSIR_RX_ONLY;
11316 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11317 }
11318 else
11319 {
11320 /* set pairwise key*/
11321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11322 "%s- %d: setting pairwise key",
11323 __func__, __LINE__);
11324 setKey.keyDirection = eSIR_TX_RX;
11325 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11326 }
11327 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11328 {
11329 setKey.keyDirection = eSIR_TX_RX;
11330 /*Set the group key*/
11331 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11332 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011333
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011334 if ( 0 != status )
11335 {
11336 hddLog(VOS_TRACE_LEVEL_ERROR,
11337 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011338 status = -EINVAL;
11339 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011340 }
11341 /*Save the keys here and call sme_RoamSetKey for setting
11342 the PTK after peer joins the IBSS network*/
11343 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11344 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011345 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011346 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011347 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11348 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11349 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011350 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011351 if( pHostapdState->bssState == BSS_START )
11352 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011353 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11354 vos_status = wlan_hdd_check_ula_done(pAdapter);
11355
11356 if ( vos_status != VOS_STATUS_SUCCESS )
11357 {
11358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11359 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11360 __LINE__, vos_status );
11361
11362 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11363
11364 status = -EINVAL;
11365 goto end;
11366 }
11367
Jeff Johnson295189b2012-06-20 16:38:30 -070011368 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11369
11370 if ( status != eHAL_STATUS_SUCCESS )
11371 {
11372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11373 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11374 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011375 status = -EINVAL;
11376 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011377 }
11378 }
11379
11380 /* Saving WEP keys */
11381 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11382 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11383 {
11384 //Save the wep key in ap context. Issue setkey after the BSS is started.
11385 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11386 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11387 }
11388 else
11389 {
11390 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011391 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011392 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11393 }
11394 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011395 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11396 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011397 {
11398 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11399 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11400
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011401#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11402 if (!pairwise)
11403#else
11404 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11405#endif
11406 {
11407 /* set group key*/
11408 if (pHddStaCtx->roam_info.deferKeyComplete)
11409 {
11410 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11411 "%s- %d: Perform Set key Complete",
11412 __func__, __LINE__);
11413 hdd_PerformRoamSetKeyComplete(pAdapter);
11414 }
11415 }
11416
Jeff Johnson295189b2012-06-20 16:38:30 -070011417 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11418
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011419 pWextState->roamProfile.Keys.defaultIndex = key_index;
11420
11421
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011422 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011423 params->key, params->key_len);
11424
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011425
Jeff Johnson295189b2012-06-20 16:38:30 -070011426 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11427
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011428 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011429 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011430 __func__, setKey.peerMac[0], setKey.peerMac[1],
11431 setKey.peerMac[2], setKey.peerMac[3],
11432 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011433 setKey.keyDirection);
11434
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011435 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011436
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011437 if ( vos_status != VOS_STATUS_SUCCESS )
11438 {
11439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011440 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11441 __LINE__, vos_status );
11442
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011443 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011444
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011445 status = -EINVAL;
11446 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011447
11448 }
11449
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011450#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011451 /* The supplicant may attempt to set the PTK once pre-authentication
11452 is done. Save the key in the UMAC and include it in the ADD BSS
11453 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011454 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011455 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011456 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011457 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11458 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011459 status = 0;
11460 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011461 }
11462 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11463 {
11464 hddLog(VOS_TRACE_LEVEL_ERROR,
11465 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011466 status = -EINVAL;
11467 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011468 }
11469#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011470
11471 /* issue set key request to SME*/
11472 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11473 pAdapter->sessionId, &setKey, &roamId );
11474
11475 if ( 0 != status )
11476 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011477 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011478 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11479 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011480 status = -EINVAL;
11481 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011482 }
11483
11484
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011485 /* in case of IBSS as there was no information available about WEP keys during
11486 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011487 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011488 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11489 !( ( IW_AUTH_KEY_MGMT_802_1X
11490 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011491 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11492 )
11493 &&
11494 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11495 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11496 )
11497 )
11498 {
11499 setKey.keyDirection = eSIR_RX_ONLY;
11500 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11501
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011502 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011503 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011504 __func__, setKey.peerMac[0], setKey.peerMac[1],
11505 setKey.peerMac[2], setKey.peerMac[3],
11506 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011507 setKey.keyDirection);
11508
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011509 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011510 pAdapter->sessionId, &setKey, &roamId );
11511
11512 if ( 0 != status )
11513 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011514 hddLog(VOS_TRACE_LEVEL_ERROR,
11515 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011516 __func__, status);
11517 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011518 status = -EINVAL;
11519 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011520 }
11521 }
11522 }
11523
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011524end:
11525 /* Need to clear any trace of key value in the memory.
11526 * Thus zero out the memory even though it is local
11527 * variable.
11528 */
11529 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011530 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011531 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011532}
11533
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011534#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11535static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11536 struct net_device *ndev,
11537 u8 key_index, bool pairwise,
11538 const u8 *mac_addr,
11539 struct key_params *params
11540 )
11541#else
11542static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11543 struct net_device *ndev,
11544 u8 key_index, const u8 *mac_addr,
11545 struct key_params *params
11546 )
11547#endif
11548{
11549 int ret;
11550 vos_ssr_protect(__func__);
11551#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11552 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11553 mac_addr, params);
11554#else
11555 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11556 params);
11557#endif
11558 vos_ssr_unprotect(__func__);
11559
11560 return ret;
11561}
11562
Jeff Johnson295189b2012-06-20 16:38:30 -070011563/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011564 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011565 * This function is used to get the key information
11566 */
11567#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011568static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011569 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011570 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011571 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011572 const u8 *mac_addr, void *cookie,
11573 void (*callback)(void *cookie, struct key_params*)
11574 )
11575#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011576static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011577 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011578 struct net_device *ndev,
11579 u8 key_index, const u8 *mac_addr, void *cookie,
11580 void (*callback)(void *cookie, struct key_params*)
11581 )
11582#endif
11583{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011584 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011585 hdd_wext_state_t *pWextState = NULL;
11586 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011587 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011588 hdd_context_t *pHddCtx;
11589 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011590
11591 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011592
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011593 if (NULL == pAdapter)
11594 {
11595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11596 "%s: HDD adapter is Null", __func__);
11597 return -ENODEV;
11598 }
11599
11600 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11601 ret = wlan_hdd_validate_context(pHddCtx);
11602 if (0 != ret)
11603 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011604 return ret;
11605 }
11606
11607 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11608 pRoamProfile = &(pWextState->roamProfile);
11609
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011610 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11611 __func__, hdd_device_modetoString(pAdapter->device_mode),
11612 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011613
Jeff Johnson295189b2012-06-20 16:38:30 -070011614 memset(&params, 0, sizeof(params));
11615
11616 if (CSR_MAX_NUM_KEY <= key_index)
11617 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011619 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011620 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011621
11622 switch(pRoamProfile->EncryptionType.encryptionType[0])
11623 {
11624 case eCSR_ENCRYPT_TYPE_NONE:
11625 params.cipher = IW_AUTH_CIPHER_NONE;
11626 break;
11627
11628 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11629 case eCSR_ENCRYPT_TYPE_WEP40:
11630 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11631 break;
11632
11633 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11634 case eCSR_ENCRYPT_TYPE_WEP104:
11635 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11636 break;
11637
11638 case eCSR_ENCRYPT_TYPE_TKIP:
11639 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11640 break;
11641
11642 case eCSR_ENCRYPT_TYPE_AES:
11643 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11644 break;
11645
11646 default:
11647 params.cipher = IW_AUTH_CIPHER_NONE;
11648 break;
11649 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011650
c_hpothuaaf19692014-05-17 17:01:48 +053011651 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11652 TRACE_CODE_HDD_CFG80211_GET_KEY,
11653 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011654
Jeff Johnson295189b2012-06-20 16:38:30 -070011655 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11656 params.seq_len = 0;
11657 params.seq = NULL;
11658 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11659 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011660 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011661 return 0;
11662}
11663
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011664#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11665static int wlan_hdd_cfg80211_get_key(
11666 struct wiphy *wiphy,
11667 struct net_device *ndev,
11668 u8 key_index, bool pairwise,
11669 const u8 *mac_addr, void *cookie,
11670 void (*callback)(void *cookie, struct key_params*)
11671 )
11672#else
11673static int wlan_hdd_cfg80211_get_key(
11674 struct wiphy *wiphy,
11675 struct net_device *ndev,
11676 u8 key_index, const u8 *mac_addr, void *cookie,
11677 void (*callback)(void *cookie, struct key_params*)
11678 )
11679#endif
11680{
11681 int ret;
11682
11683 vos_ssr_protect(__func__);
11684#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11685 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
11686 mac_addr, cookie, callback);
11687#else
11688 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
11689 callback);
11690#endif
11691 vos_ssr_unprotect(__func__);
11692
11693 return ret;
11694}
11695
Jeff Johnson295189b2012-06-20 16:38:30 -070011696/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011697 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011698 * This function is used to delete the key information
11699 */
11700#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011701static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011702 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011703 u8 key_index,
11704 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011705 const u8 *mac_addr
11706 )
11707#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011708static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011709 struct net_device *ndev,
11710 u8 key_index,
11711 const u8 *mac_addr
11712 )
11713#endif
11714{
11715 int status = 0;
11716
11717 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011718 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070011719 //it is observed that this is invalidating peer
11720 //key index whenever re-key is done. This is affecting data link.
11721 //It should be ok to ignore del_key.
11722#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011723 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
11724 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011725 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11726 tCsrRoamSetKey setKey;
11727 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011728
Jeff Johnson295189b2012-06-20 16:38:30 -070011729 ENTER();
11730
11731 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
11732 __func__,pAdapter->device_mode);
11733
11734 if (CSR_MAX_NUM_KEY <= key_index)
11735 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011736 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 key_index);
11738
11739 return -EINVAL;
11740 }
11741
11742 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11743 setKey.keyId = key_index;
11744
11745 if (mac_addr)
11746 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11747 else
11748 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
11749
11750 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
11751
11752 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011753 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011754 )
11755 {
11756
11757 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070011758 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11759 if( pHostapdState->bssState == BSS_START)
11760 {
11761 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011762
Jeff Johnson295189b2012-06-20 16:38:30 -070011763 if ( status != eHAL_STATUS_SUCCESS )
11764 {
11765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11766 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11767 __LINE__, status );
11768 }
11769 }
11770 }
11771 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011772 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070011773 )
11774 {
11775 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11776
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011777 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11778
11779 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011780 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011781 __func__, setKey.peerMac[0], setKey.peerMac[1],
11782 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070011783 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011784 if(pAdapter->sessionCtx.station.conn_info.connState ==
11785 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070011786 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011787 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011788 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011789
Jeff Johnson295189b2012-06-20 16:38:30 -070011790 if ( 0 != status )
11791 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011792 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011793 "%s: sme_RoamSetKey failure, returned %d",
11794 __func__, status);
11795 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11796 return -EINVAL;
11797 }
11798 }
11799 }
11800#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011801 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011802 return status;
11803}
11804
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011805#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11806static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11807 struct net_device *ndev,
11808 u8 key_index,
11809 bool pairwise,
11810 const u8 *mac_addr
11811 )
11812#else
11813static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11814 struct net_device *ndev,
11815 u8 key_index,
11816 const u8 *mac_addr
11817 )
11818#endif
11819{
11820 int ret;
11821
11822 vos_ssr_protect(__func__);
11823#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11824 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
11825 mac_addr);
11826#else
11827 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
11828#endif
11829 vos_ssr_unprotect(__func__);
11830
11831 return ret;
11832}
11833
Jeff Johnson295189b2012-06-20 16:38:30 -070011834/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011835 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011836 * This function is used to set the default tx key index
11837 */
11838#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011839static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011840 struct net_device *ndev,
11841 u8 key_index,
11842 bool unicast, bool multicast)
11843#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011844static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011845 struct net_device *ndev,
11846 u8 key_index)
11847#endif
11848{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011849 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011850 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011851 hdd_wext_state_t *pWextState;
11852 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011853 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011854
11855 ENTER();
11856
Gopichand Nakkala29149562013-05-10 21:43:41 +053011857 if ((NULL == pAdapter))
11858 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011860 "invalid adapter");
11861 return -EINVAL;
11862 }
11863
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011864 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11865 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
11866 pAdapter->sessionId, key_index));
11867
Gopichand Nakkala29149562013-05-10 21:43:41 +053011868 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11869 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11870
11871 if ((NULL == pWextState) || (NULL == pHddStaCtx))
11872 {
11873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11874 "invalid Wext state or HDD context");
11875 return -EINVAL;
11876 }
11877
Arif Hussain6d2a3322013-11-17 19:50:10 -080011878 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011879 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011880
Jeff Johnson295189b2012-06-20 16:38:30 -070011881 if (CSR_MAX_NUM_KEY <= key_index)
11882 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011883 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011884 key_index);
11885
11886 return -EINVAL;
11887 }
11888
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011889 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11890 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011891 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011892 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011893 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011894 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011895
Jeff Johnson295189b2012-06-20 16:38:30 -070011896 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011897 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011898 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011899 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011900 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080011901 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011902 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080011903 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070011904 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011905 {
11906 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070011907 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011908
Jeff Johnson295189b2012-06-20 16:38:30 -070011909 tCsrRoamSetKey setKey;
11910 v_U32_t roamId= 0xFF;
11911 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011912
11913 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011914 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011915
Jeff Johnson295189b2012-06-20 16:38:30 -070011916 Keys->defaultIndex = (u8)key_index;
11917 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11918 setKey.keyId = key_index;
11919 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011920
11921 vos_mem_copy(&setKey.Key[0],
11922 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011923 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011924
Gopichand Nakkala29149562013-05-10 21:43:41 +053011925 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011926
11927 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070011928 &pHddStaCtx->conn_info.bssId[0],
11929 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011930
Gopichand Nakkala29149562013-05-10 21:43:41 +053011931 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
11932 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
11933 eCSR_ENCRYPT_TYPE_WEP104)
11934 {
11935 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
11936 even though ap is configured for WEP-40 encryption. In this canse the key length
11937 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
11938 type(104) and switching encryption type to 40*/
11939 pWextState->roamProfile.EncryptionType.encryptionType[0] =
11940 eCSR_ENCRYPT_TYPE_WEP40;
11941 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
11942 eCSR_ENCRYPT_TYPE_WEP40;
11943 }
11944
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011945 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011946 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011947
Jeff Johnson295189b2012-06-20 16:38:30 -070011948 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011949 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011950 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011951
Jeff Johnson295189b2012-06-20 16:38:30 -070011952 if ( 0 != status )
11953 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011954 hddLog(VOS_TRACE_LEVEL_ERROR,
11955 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011956 status);
11957 return -EINVAL;
11958 }
11959 }
11960 }
11961
11962 /* In SoftAp mode setting key direction for default mode */
11963 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
11964 {
11965 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
11966 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
11967 (eCSR_ENCRYPT_TYPE_AES !=
11968 pWextState->roamProfile.EncryptionType.encryptionType[0])
11969 )
11970 {
11971 /* Saving key direction for default key index to TX default */
11972 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11973 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
11974 }
11975 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011976 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011977 return status;
11978}
11979
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011980#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11981static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11982 struct net_device *ndev,
11983 u8 key_index,
11984 bool unicast, bool multicast)
11985#else
11986static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11987 struct net_device *ndev,
11988 u8 key_index)
11989#endif
11990{
11991 int ret;
11992 vos_ssr_protect(__func__);
11993#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11994 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
11995 multicast);
11996#else
11997 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
11998#endif
11999 vos_ssr_unprotect(__func__);
12000
12001 return ret;
12002}
12003
Jeff Johnson295189b2012-06-20 16:38:30 -070012004/*
12005 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12006 * This function is used to inform the BSS details to nl80211 interface.
12007 */
12008static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12009 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12010{
12011 struct net_device *dev = pAdapter->dev;
12012 struct wireless_dev *wdev = dev->ieee80211_ptr;
12013 struct wiphy *wiphy = wdev->wiphy;
12014 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12015 int chan_no;
12016 int ie_length;
12017 const char *ie;
12018 unsigned int freq;
12019 struct ieee80211_channel *chan;
12020 int rssi = 0;
12021 struct cfg80211_bss *bss = NULL;
12022
Jeff Johnson295189b2012-06-20 16:38:30 -070012023 if( NULL == pBssDesc )
12024 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012025 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012026 return bss;
12027 }
12028
12029 chan_no = pBssDesc->channelId;
12030 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12031 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12032
12033 if( NULL == ie )
12034 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012035 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012036 return bss;
12037 }
12038
12039#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12040 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12041 {
12042 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12043 }
12044 else
12045 {
12046 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12047 }
12048#else
12049 freq = ieee80211_channel_to_frequency(chan_no);
12050#endif
12051
12052 chan = __ieee80211_get_channel(wiphy, freq);
12053
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012054 if (!chan) {
12055 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12056 return NULL;
12057 }
12058
Abhishek Singhaee43942014-06-16 18:55:47 +053012059 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012060
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012061 return cfg80211_inform_bss(wiphy, chan,
12062#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12063 CFG80211_BSS_FTYPE_UNKNOWN,
12064#endif
12065 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012066 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012067 pBssDesc->capabilityInfo,
12068 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012069 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012070}
12071
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012072/*
12073 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12074 * interface that BSS might have been lost.
12075 * @pAdapter: adaptor
12076 * @bssid: bssid which might have been lost
12077 *
12078 * Return: bss which is unlinked from kernel cache
12079 */
12080struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12081 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12082{
12083 struct net_device *dev = pAdapter->dev;
12084 struct wireless_dev *wdev = dev->ieee80211_ptr;
12085 struct wiphy *wiphy = wdev->wiphy;
12086 struct cfg80211_bss *bss = NULL;
12087
12088 bss = cfg80211_get_bss(wiphy, NULL, bssid,
12089 NULL,
12090 0,
12091#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && !defined(WITH_BACKPORTS) \
12092 && !defined(IEEE80211_PRIVACY)
12093 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
12094#else
12095 IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
12096#endif
12097 if (bss == NULL) {
12098 hddLog(LOGE, FL("BSS not present"));
12099 } else {
12100 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12101 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12102 cfg80211_unlink_bss(wiphy, bss);
12103 }
12104 return bss;
12105}
Jeff Johnson295189b2012-06-20 16:38:30 -070012106
12107
12108/*
12109 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12110 * This function is used to inform the BSS details to nl80211 interface.
12111 */
12112struct cfg80211_bss*
12113wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12114 tSirBssDescription *bss_desc
12115 )
12116{
12117 /*
12118 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12119 already exists in bss data base of cfg80211 for that particular BSS ID.
12120 Using cfg80211_inform_bss_frame to update the bss entry instead of
12121 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12122 now there is no possibility to get the mgmt(probe response) frame from PE,
12123 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12124 cfg80211_inform_bss_frame.
12125 */
12126 struct net_device *dev = pAdapter->dev;
12127 struct wireless_dev *wdev = dev->ieee80211_ptr;
12128 struct wiphy *wiphy = wdev->wiphy;
12129 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012130#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12131 qcom_ie_age *qie_age = NULL;
12132 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12133#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012134 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012135#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012136 const char *ie =
12137 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12138 unsigned int freq;
12139 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012140 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012141 struct cfg80211_bss *bss_status = NULL;
12142 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12143 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012144 hdd_context_t *pHddCtx;
12145 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012146#ifdef WLAN_OPEN_SOURCE
12147 struct timespec ts;
12148#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012149
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012150
Wilson Yangf80a0542013-10-07 13:02:37 -070012151 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12152 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012153 if (0 != status)
12154 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012155 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012156 }
12157
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012158 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012159 if (!mgmt)
12160 {
12161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12162 "%s: memory allocation failed ", __func__);
12163 return NULL;
12164 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012165
Jeff Johnson295189b2012-06-20 16:38:30 -070012166 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012167
12168#ifdef WLAN_OPEN_SOURCE
12169 /* Android does not want the timestamp from the frame.
12170 Instead it wants a monotonic increasing value */
12171 get_monotonic_boottime(&ts);
12172 mgmt->u.probe_resp.timestamp =
12173 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12174#else
12175 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012176 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12177 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012178
12179#endif
12180
Jeff Johnson295189b2012-06-20 16:38:30 -070012181 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12182 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012183
12184#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12185 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12186 /* Assuming this is the last IE, copy at the end */
12187 ie_length -=sizeof(qcom_ie_age);
12188 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12189 qie_age->element_id = QCOM_VENDOR_IE_ID;
12190 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12191 qie_age->oui_1 = QCOM_OUI1;
12192 qie_age->oui_2 = QCOM_OUI2;
12193 qie_age->oui_3 = QCOM_OUI3;
12194 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Deepthi Gowri4480a3f2016-05-18 19:30:17 +053012195 qie_age->age = vos_timer_get_system_time() - bss_desc->nReceivedTime;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012196#endif
12197
Jeff Johnson295189b2012-06-20 16:38:30 -070012198 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012199 if (bss_desc->fProbeRsp)
12200 {
12201 mgmt->frame_control |=
12202 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12203 }
12204 else
12205 {
12206 mgmt->frame_control |=
12207 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12208 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012209
12210#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012211 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012212 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12213 {
12214 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12215 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012216 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012217 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12218
12219 {
12220 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12221 }
12222 else
12223 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012224 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12225 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012226 kfree(mgmt);
12227 return NULL;
12228 }
12229#else
12230 freq = ieee80211_channel_to_frequency(chan_no);
12231#endif
12232 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012233 /*when the band is changed on the fly using the GUI, three things are done
12234 * 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)
12235 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12236 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12237 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12238 * and discards the channels correponding to previous band and calls back with zero bss results.
12239 * 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
12240 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12241 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12242 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12243 * So drop the bss and continue to next bss.
12244 */
12245 if(chan == NULL)
12246 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053012247 hddLog(VOS_TRACE_LEVEL_ERROR,
12248 FL("chan pointer is NULL, chan_no: %d freq: %d"),
12249 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070012250 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012251 return NULL;
12252 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012253 /*To keep the rssi icon of the connected AP in the scan window
12254 *and the rssi icon of the wireless networks in sync
12255 * */
12256 if (( eConnectionState_Associated ==
12257 pAdapter->sessionCtx.station.conn_info.connState ) &&
12258 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12259 pAdapter->sessionCtx.station.conn_info.bssId,
12260 WNI_CFG_BSSID_LEN)) &&
12261 (pHddCtx->hdd_wlan_suspended == FALSE))
12262 {
12263 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12264 rssi = (pAdapter->rssi * 100);
12265 }
12266 else
12267 {
12268 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12269 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012270
Nirav Shah20ac06f2013-12-12 18:14:06 +053012271 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012272 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12273 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012274
Jeff Johnson295189b2012-06-20 16:38:30 -070012275 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12276 frame_len, rssi, GFP_KERNEL);
12277 kfree(mgmt);
12278 return bss_status;
12279}
12280
12281/*
12282 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12283 * This function is used to update the BSS data base of CFG8011
12284 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012285struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012286 tCsrRoamInfo *pRoamInfo
12287 )
12288{
12289 tCsrRoamConnectedProfile roamProfile;
12290 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12291 struct cfg80211_bss *bss = NULL;
12292
12293 ENTER();
12294
12295 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12296 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12297
12298 if (NULL != roamProfile.pBssDesc)
12299 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012300 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12301 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012302
12303 if (NULL == bss)
12304 {
12305 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12306 __func__);
12307 }
12308
12309 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12310 }
12311 else
12312 {
12313 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12314 __func__);
12315 }
12316 return bss;
12317}
12318
12319/*
12320 * FUNCTION: wlan_hdd_cfg80211_update_bss
12321 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012322static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12323 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012324 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012325{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012326 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012327 tCsrScanResultInfo *pScanResult;
12328 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012329 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012330 tScanResultHandle pResult;
12331 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012332 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012333 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012334 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012335
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012336 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12337 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12338 NO_SESSION, pAdapter->sessionId));
12339
Wilson Yangf80a0542013-10-07 13:02:37 -070012340 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012341 ret = wlan_hdd_validate_context(pHddCtx);
12342 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070012343 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012344 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070012345 }
12346
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012347 if (pAdapter->request != NULL)
12348 {
12349 if ((pAdapter->request->n_ssids == 1)
12350 && (pAdapter->request->ssids != NULL)
12351 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12352 is_p2p_scan = true;
12353 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012354 /*
12355 * start getting scan results and populate cgf80211 BSS database
12356 */
12357 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12358
12359 /* no scan results */
12360 if (NULL == pResult)
12361 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012362 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12363 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012364 wlan_hdd_get_frame_logs(pAdapter,
12365 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012366 return status;
12367 }
12368
12369 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12370
12371 while (pScanResult)
12372 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012373 /*
12374 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12375 * entry already exists in bss data base of cfg80211 for that
12376 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12377 * bss entry instead of cfg80211_inform_bss, But this call expects
12378 * mgmt packet as input. As of now there is no possibility to get
12379 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012380 * ieee80211_mgmt(probe response) and passing to c
12381 * fg80211_inform_bss_frame.
12382 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012383 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12384 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12385 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012386 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12387 continue; //Skip the non p2p bss entries
12388 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012389 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12390 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012391
Jeff Johnson295189b2012-06-20 16:38:30 -070012392
12393 if (NULL == bss_status)
12394 {
12395 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012396 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012397 }
12398 else
12399 {
Yue Maf49ba872013-08-19 12:04:25 -070012400 cfg80211_put_bss(
12401#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12402 wiphy,
12403#endif
12404 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012405 }
12406
12407 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12408 }
12409
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012410 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012411 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012412 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012413}
12414
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012415void
12416hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12417{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012418 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012419 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012420} /****** end hddPrintMacAddr() ******/
12421
12422void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012423hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012424{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012425 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012426 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012427 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12428 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12429 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012430} /****** end hddPrintPmkId() ******/
12431
12432//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12433//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12434
12435//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12436//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12437
12438#define dump_bssid(bssid) \
12439 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012440 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12441 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012442 }
12443
12444#define dump_pmkid(pMac, pmkid) \
12445 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012446 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12447 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012448 }
12449
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012450#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012451/*
12452 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12453 * This function is used to notify the supplicant of a new PMKSA candidate.
12454 */
12455int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012456 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012457 int index, bool preauth )
12458{
Jeff Johnsone7245742012-09-05 17:12:55 -070012459#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012460 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012461 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012462
12463 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012464 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012465
12466 if( NULL == pRoamInfo )
12467 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012468 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012469 return -EINVAL;
12470 }
12471
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012472 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12473 {
12474 dump_bssid(pRoamInfo->bssid);
12475 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012476 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012477 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012478#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012479 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012480}
12481#endif //FEATURE_WLAN_LFR
12482
Yue Maef608272013-04-08 23:09:17 -070012483#ifdef FEATURE_WLAN_LFR_METRICS
12484/*
12485 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12486 * 802.11r/LFR metrics reporting function to report preauth initiation
12487 *
12488 */
12489#define MAX_LFR_METRICS_EVENT_LENGTH 100
12490VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12491 tCsrRoamInfo *pRoamInfo)
12492{
12493 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12494 union iwreq_data wrqu;
12495
12496 ENTER();
12497
12498 if (NULL == pAdapter)
12499 {
12500 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12501 return VOS_STATUS_E_FAILURE;
12502 }
12503
12504 /* create the event */
12505 memset(&wrqu, 0, sizeof(wrqu));
12506 memset(metrics_notification, 0, sizeof(metrics_notification));
12507
12508 wrqu.data.pointer = metrics_notification;
12509 wrqu.data.length = scnprintf(metrics_notification,
12510 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12511 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12512
12513 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12514
12515 EXIT();
12516
12517 return VOS_STATUS_SUCCESS;
12518}
12519
12520/*
12521 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12522 * 802.11r/LFR metrics reporting function to report preauth completion
12523 * or failure
12524 */
12525VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12526 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12527{
12528 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12529 union iwreq_data wrqu;
12530
12531 ENTER();
12532
12533 if (NULL == pAdapter)
12534 {
12535 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12536 return VOS_STATUS_E_FAILURE;
12537 }
12538
12539 /* create the event */
12540 memset(&wrqu, 0, sizeof(wrqu));
12541 memset(metrics_notification, 0, sizeof(metrics_notification));
12542
12543 scnprintf(metrics_notification, sizeof(metrics_notification),
12544 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12545 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12546
12547 if (1 == preauth_status)
12548 strncat(metrics_notification, " TRUE", 5);
12549 else
12550 strncat(metrics_notification, " FALSE", 6);
12551
12552 wrqu.data.pointer = metrics_notification;
12553 wrqu.data.length = strlen(metrics_notification);
12554
12555 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12556
12557 EXIT();
12558
12559 return VOS_STATUS_SUCCESS;
12560}
12561
12562/*
12563 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12564 * 802.11r/LFR metrics reporting function to report handover initiation
12565 *
12566 */
12567VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12568 tCsrRoamInfo *pRoamInfo)
12569{
12570 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12571 union iwreq_data wrqu;
12572
12573 ENTER();
12574
12575 if (NULL == pAdapter)
12576 {
12577 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12578 return VOS_STATUS_E_FAILURE;
12579 }
12580
12581 /* create the event */
12582 memset(&wrqu, 0, sizeof(wrqu));
12583 memset(metrics_notification, 0, sizeof(metrics_notification));
12584
12585 wrqu.data.pointer = metrics_notification;
12586 wrqu.data.length = scnprintf(metrics_notification,
12587 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12588 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12589
12590 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12591
12592 EXIT();
12593
12594 return VOS_STATUS_SUCCESS;
12595}
12596#endif
12597
Jeff Johnson295189b2012-06-20 16:38:30 -070012598/*
12599 * FUNCTION: hdd_cfg80211_scan_done_callback
12600 * scanning callback function, called after finishing scan
12601 *
12602 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012603static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012604 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12605{
12606 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012607 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012608 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012609 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012610 struct cfg80211_scan_request *req = NULL;
12611 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012612 bool aborted = false;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012613#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12614 bool iface_down = false;
12615#endif
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012616 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012617 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012618 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012619
12620 ENTER();
12621
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012622 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012623 if (NULL == pHddCtx) {
12624 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012625 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012626 }
12627
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012628#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12629 if (!(pAdapter->dev->flags & IFF_UP))
12630 {
12631 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012632 iface_down = true;
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012633 }
12634#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012635 pScanInfo = &pHddCtx->scan_info;
12636
Jeff Johnson295189b2012-06-20 16:38:30 -070012637 hddLog(VOS_TRACE_LEVEL_INFO,
12638 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012639 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012640 __func__, halHandle, pContext, (int) scanId, (int) status);
12641
Kiet Lamac06e2c2013-10-23 16:25:07 +053012642 pScanInfo->mScanPendingCounter = 0;
12643
Jeff Johnson295189b2012-06-20 16:38:30 -070012644 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012645 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012646 &pScanInfo->scan_req_completion_event,
12647 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012648 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012649 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012650 hddLog(VOS_TRACE_LEVEL_ERROR,
12651 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012652 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012653 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012654 }
12655
Yue Maef608272013-04-08 23:09:17 -070012656 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012657 {
12658 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012659 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012660 }
12661
12662 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012663 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012664 {
12665 hddLog(VOS_TRACE_LEVEL_INFO,
12666 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012667 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012668 (int) scanId);
12669 }
12670
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012671#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012672 if (!iface_down)
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012673#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012674 {
12675 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
12676 pAdapter);
12677 if (0 > ret)
12678 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012679 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012680
Jeff Johnson295189b2012-06-20 16:38:30 -070012681 /* If any client wait scan result through WEXT
12682 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012683 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012684 {
12685 /* The other scan request waiting for current scan finish
12686 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012687 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012688 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012689 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012690 }
12691 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012692 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012693 {
12694 struct net_device *dev = pAdapter->dev;
12695 union iwreq_data wrqu;
12696 int we_event;
12697 char *msg;
12698
12699 memset(&wrqu, '\0', sizeof(wrqu));
12700 we_event = SIOCGIWSCAN;
12701 msg = NULL;
12702 wireless_send_event(dev, we_event, &wrqu, msg);
12703 }
12704 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012705 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012706
12707 /* Get the Scan Req */
12708 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053012709 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012710
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012711 /* Scan is no longer pending */
12712 pScanInfo->mScanPending = VOS_FALSE;
12713
mukul sharmae7041822015-12-03 15:09:21 +053012714 if (!req || req->wiphy == NULL)
Jeff Johnson295189b2012-06-20 16:38:30 -070012715 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012716 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
mukul sharmae7041822015-12-03 15:09:21 +053012717 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070012718 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012719 }
12720
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012721 /* last_scan_timestamp is used to decide if new scan
12722 * is needed or not on station interface. If last station
12723 * scan time and new station scan time is less then
12724 * last_scan_timestamp ; driver will return cached scan.
12725 */
12726 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12727 {
12728 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12729
12730 if ( req->n_channels )
12731 {
12732 for (i = 0; i < req->n_channels ; i++ )
12733 {
12734 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12735 }
12736 /* store no of channel scanned */
12737 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
12738 }
12739
12740 }
12741
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070012742 /*
12743 * cfg80211_scan_done informing NL80211 about completion
12744 * of scanning
12745 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012746 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
12747 {
12748 aborted = true;
12749 }
mukul sharmae7041822015-12-03 15:09:21 +053012750
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012751#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12752 if (!iface_down)
12753#endif
12754 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053012755
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012756 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070012757
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012758allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053012759 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
12760 ) && (pHddCtx->spoofMacAddr.isEnabled
12761 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053012762 /* Generate new random mac addr for next scan */
12763 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053012764
12765 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
12766 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053012767 }
12768
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012769 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012770 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012771
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012772 /* Acquire wakelock to handle the case where APP's tries to suspend
12773 * immediatly after the driver gets connect request(i.e after scan)
12774 * from supplicant, this result in app's is suspending and not able
12775 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012776 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012777
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012778#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12779 if (!iface_down)
12780#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012781#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012782 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012783#endif
12784
Jeff Johnson295189b2012-06-20 16:38:30 -070012785 EXIT();
12786 return 0;
12787}
12788
12789/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053012790 * FUNCTION: hdd_isConnectionInProgress
12791 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012792 *
12793 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012794v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012795{
12796 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12797 hdd_station_ctx_t *pHddStaCtx = NULL;
12798 hdd_adapter_t *pAdapter = NULL;
12799 VOS_STATUS status = 0;
12800 v_U8_t staId = 0;
12801 v_U8_t *staMac = NULL;
12802
c_hpothu9b781ba2013-12-30 20:57:45 +053012803 if (TRUE == pHddCtx->btCoexModeSet)
12804 {
12805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053012806 FL("BTCoex Mode operation in progress"));
12807 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053012808 }
12809
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012810 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12811
12812 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12813 {
12814 pAdapter = pAdapterNode->pAdapter;
12815
12816 if( pAdapter )
12817 {
12818 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012819 "%s: Adapter with device mode %s (%d) exists",
12820 __func__, hdd_device_modetoString(pAdapter->device_mode),
12821 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012822 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053012823 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12824 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
12825 (eConnectionState_Connecting ==
12826 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12827 {
12828 hddLog(VOS_TRACE_LEVEL_ERROR,
12829 "%s: %p(%d) Connection is in progress", __func__,
12830 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12831 return VOS_TRUE;
12832 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012833 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053012834 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012835 {
12836 hddLog(VOS_TRACE_LEVEL_ERROR,
12837 "%s: %p(%d) Reassociation is in progress", __func__,
12838 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12839 return VOS_TRUE;
12840 }
12841 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012842 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12843 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012844 {
12845 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12846 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012847 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012848 {
12849 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
12850 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012851 "%s: client " MAC_ADDRESS_STR
12852 " is in the middle of WPS/EAPOL exchange.", __func__,
12853 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012854 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012855 }
12856 }
12857 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
12858 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
12859 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012860 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12861 ptSapContext pSapCtx = NULL;
12862 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12863 if(pSapCtx == NULL){
12864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12865 FL("psapCtx is NULL"));
12866 return VOS_FALSE;
12867 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012868 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
12869 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012870 if ((pSapCtx->aStaInfo[staId].isUsed) &&
12871 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012872 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012873 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012874
12875 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012876 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
12877 "middle of WPS/EAPOL exchange.", __func__,
12878 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012879 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012880 }
12881 }
12882 }
12883 }
12884 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12885 pAdapterNode = pNext;
12886 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053012887 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012888}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012889
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053012890/**
12891 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
12892 * to the Scan request
12893 * @scanRequest: Pointer to the csr scan request
12894 * @request: Pointer to the scan request from supplicant
12895 *
12896 * Return: None
12897 */
12898#ifdef CFG80211_SCAN_BSSID
12899static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
12900 struct cfg80211_scan_request *request)
12901{
12902 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
12903}
12904#else
12905static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
12906 struct cfg80211_scan_request *request)
12907{
12908}
12909#endif
12910
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012911/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012912 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070012913 * this scan respond to scan trigger and update cfg80211 scan database
12914 * later, scan dump command can be used to recieve scan results
12915 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012916int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080012917#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12918 struct net_device *dev,
12919#endif
12920 struct cfg80211_scan_request *request)
12921{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012922 hdd_adapter_t *pAdapter = NULL;
12923 hdd_context_t *pHddCtx = NULL;
12924 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012925 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012926 tCsrScanRequest scanRequest;
12927 tANI_U8 *channelList = NULL, i;
12928 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012929 int status;
12930 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012931 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012932 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053012933 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053012934 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012935
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012936#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
12937 struct net_device *dev = NULL;
12938 if (NULL == request)
12939 {
12940 hddLog(VOS_TRACE_LEVEL_ERROR,
12941 "%s: scan req param null", __func__);
12942 return -EINVAL;
12943 }
12944 dev = request->wdev->netdev;
12945#endif
12946
12947 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12948 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
12949 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12950
Jeff Johnson295189b2012-06-20 16:38:30 -070012951 ENTER();
12952
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012953 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12954 __func__, hdd_device_modetoString(pAdapter->device_mode),
12955 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012956
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012957 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012958 if (0 != status)
12959 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012960 return status;
12961 }
12962
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012963 if (NULL == pwextBuf)
12964 {
12965 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
12966 __func__);
12967 return -EIO;
12968 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012969 cfg_param = pHddCtx->cfg_ini;
12970 pScanInfo = &pHddCtx->scan_info;
12971
Jeff Johnson295189b2012-06-20 16:38:30 -070012972#ifdef WLAN_BTAMP_FEATURE
12973 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012974 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070012975 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080012976 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012977 "%s: No scanning when AMP is on", __func__);
12978 return -EOPNOTSUPP;
12979 }
12980#endif
12981 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012982 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012983 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012984 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012985 "%s: Not scanning on device_mode = %s (%d)",
12986 __func__, hdd_device_modetoString(pAdapter->device_mode),
12987 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012988 return -EOPNOTSUPP;
12989 }
12990
12991 if (TRUE == pScanInfo->mScanPending)
12992 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012993 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
12994 {
12995 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
12996 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012997 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012998 }
12999
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013000 // Don't allow scan if PNO scan is going on.
13001 if (pHddCtx->isPnoEnable)
13002 {
13003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13004 FL("pno scan in progress"));
13005 return -EBUSY;
13006 }
13007
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013008 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013009 //Channel and action frame is pending
13010 //Otherwise Cancel Remain On Channel and allow Scan
13011 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013012 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013013 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013014 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013015 return -EBUSY;
13016 }
13017
Jeff Johnson295189b2012-06-20 16:38:30 -070013018 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13019 {
13020 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013021 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013022 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013023 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013024 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13025 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013026 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013027 "%s: MAX TM Level Scan not allowed", __func__);
13028 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013029 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013030 }
13031 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13032
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013033 /* Check if scan is allowed at this point of time.
13034 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013035 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013036 {
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013037 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
13038 if (SCAN_ABORT_THRESHOLD < pHddCtx->con_scan_abort_cnt) {
13039 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13040 FL("Triggering SSR, SSR status = %d"), status);
13041 vos_wlanRestart();
13042 }
13043 else
13044 pHddCtx->con_scan_abort_cnt++;
13045
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013046 return -EBUSY;
13047 }
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013048 pHddCtx->con_scan_abort_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013049
Jeff Johnson295189b2012-06-20 16:38:30 -070013050 vos_mem_zero( &scanRequest, sizeof(scanRequest));
13051
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013052 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
13053 * Becasue of this, driver is assuming that this is not wildcard scan and so
13054 * is not aging out the scan results.
13055 */
13056 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070013057 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013058 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013059 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013060
13061 if ((request->ssids) && (0 < request->n_ssids))
13062 {
13063 tCsrSSIDInfo *SsidInfo;
13064 int j;
13065 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
13066 /* Allocate num_ssid tCsrSSIDInfo structure */
13067 SsidInfo = scanRequest.SSIDs.SSIDList =
13068 ( tCsrSSIDInfo *)vos_mem_malloc(
13069 request->n_ssids*sizeof(tCsrSSIDInfo));
13070
13071 if(NULL == scanRequest.SSIDs.SSIDList)
13072 {
13073 hddLog(VOS_TRACE_LEVEL_ERROR,
13074 "%s: memory alloc failed SSIDInfo buffer", __func__);
13075 return -ENOMEM;
13076 }
13077
13078 /* copy all the ssid's and their length */
13079 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
13080 {
13081 /* get the ssid length */
13082 SsidInfo->SSID.length = request->ssids[j].ssid_len;
13083 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
13084 SsidInfo->SSID.length);
13085 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
13086 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
13087 j, SsidInfo->SSID.ssId);
13088 }
13089 /* set the scan type to active */
13090 scanRequest.scanType = eSIR_ACTIVE_SCAN;
13091 }
13092 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013093 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013094 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13095 TRACE_CODE_HDD_CFG80211_SCAN,
13096 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070013097 /* set the scan type to active */
13098 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070013099 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013100 else
13101 {
13102 /*Set the scan type to default type, in this case it is ACTIVE*/
13103 scanRequest.scanType = pScanInfo->scan_mode;
13104 }
13105 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
13106 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070013107
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013108 csr_scan_request_assign_bssid(&scanRequest, request);
13109
Jeff Johnson295189b2012-06-20 16:38:30 -070013110 /* set BSSType to default type */
13111 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
13112
13113 /*TODO: scan the requested channels only*/
13114
13115 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013116 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070013117 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013118 hddLog(VOS_TRACE_LEVEL_WARN,
13119 "No of Scan Channels exceeded limit: %d", request->n_channels);
13120 request->n_channels = MAX_CHANNEL;
13121 }
13122
13123 hddLog(VOS_TRACE_LEVEL_INFO,
13124 "No of Scan Channels: %d", request->n_channels);
13125
13126
13127 if( request->n_channels )
13128 {
13129 char chList [(request->n_channels*5)+1];
13130 int len;
13131 channelList = vos_mem_malloc( request->n_channels );
13132 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053013133 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013134 hddLog(VOS_TRACE_LEVEL_ERROR,
13135 "%s: memory alloc failed channelList", __func__);
13136 status = -ENOMEM;
13137 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053013138 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013139
13140 for( i = 0, len = 0; i < request->n_channels ; i++ )
13141 {
13142 channelList[i] = request->channels[i]->hw_value;
13143 len += snprintf(chList+len, 5, "%d ", channelList[i]);
13144 }
13145
Nirav Shah20ac06f2013-12-12 18:14:06 +053013146 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013147 "Channel-List: %s ", chList);
13148 }
c_hpothu53512302014-04-15 18:49:53 +053013149
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013150 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13151 scanRequest.ChannelInfo.ChannelList = channelList;
13152
13153 /* set requestType to full scan */
13154 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13155
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013156 /* if there is back to back scan happening in driver with in
13157 * nDeferScanTimeInterval interval driver should defer new scan request
13158 * and should provide last cached scan results instead of new channel list.
13159 * This rule is not applicable if scan is p2p scan.
13160 * This condition will work only in case when last request no of channels
13161 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013162 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013163 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013164 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013165
Sushant Kaushik86592172015-04-27 16:35:03 +053013166 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13167 /* if wps ie is NULL , then only defer scan */
13168 if ( pWpsIe == NULL &&
13169 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013170 {
13171 if ( pScanInfo->last_scan_timestamp !=0 &&
13172 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13173 {
13174 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13175 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13176 vos_mem_compare(pScanInfo->last_scan_channelList,
13177 channelList, pScanInfo->last_scan_numChannels))
13178 {
13179 hddLog(VOS_TRACE_LEVEL_WARN,
13180 " New and old station scan time differ is less then %u",
13181 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13182
13183 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013184 pAdapter);
13185
Agarwal Ashish57e84372014-12-05 18:26:53 +053013186 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013187 "Return old cached scan as all channels and no of channels are same");
13188
Agarwal Ashish57e84372014-12-05 18:26:53 +053013189 if (0 > ret)
13190 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013191
Agarwal Ashish57e84372014-12-05 18:26:53 +053013192 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013193
13194 status = eHAL_STATUS_SUCCESS;
13195 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013196 }
13197 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013198 }
13199
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013200 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13201 * search (Flush on both full scan and social scan but not on single
13202 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13203 */
13204
13205 /* Supplicant does single channel scan after 8-way handshake
13206 * and in that case driver shoudnt flush scan results. If
13207 * driver flushes the scan results here and unfortunately if
13208 * the AP doesnt respond to our probe req then association
13209 * fails which is not desired
13210 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013211 if ((request->n_ssids == 1)
13212 && (request->ssids != NULL)
13213 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13214 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013215
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013216 if( is_p2p_scan ||
13217 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013218 {
13219 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13220 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13221 pAdapter->sessionId );
13222 }
13223
13224 if( request->ie_len )
13225 {
13226 /* save this for future association (join requires this) */
13227 /*TODO: Array needs to be converted to dynamic allocation,
13228 * as multiple ie.s can be sent in cfg80211_scan_request structure
13229 * CR 597966
13230 */
13231 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13232 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13233 pScanInfo->scanAddIE.length = request->ie_len;
13234
13235 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13236 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13237 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013238 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013239 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013240 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013241 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13242 memcpy( pwextBuf->roamProfile.addIEScan,
13243 request->ie, request->ie_len);
13244 }
13245 else
13246 {
13247 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13248 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013249 }
13250
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013251 }
13252 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13253 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13254
13255 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13256 request->ie_len);
13257 if (pP2pIe != NULL)
13258 {
13259#ifdef WLAN_FEATURE_P2P_DEBUG
13260 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13261 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13262 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013263 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013264 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13265 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13266 "Go nego completed to Connection is started");
13267 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13268 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013269 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013270 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13271 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013272 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013273 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13274 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13275 "Disconnected state to Connection is started");
13276 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13277 "for 4way Handshake");
13278 }
13279#endif
13280
13281 /* no_cck will be set during p2p find to disable 11b rates */
13282 if(TRUE == request->no_cck)
13283 {
13284 hddLog(VOS_TRACE_LEVEL_INFO,
13285 "%s: This is a P2P Search", __func__);
13286 scanRequest.p2pSearch = 1;
13287
13288 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013289 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013290 /* set requestType to P2P Discovery */
13291 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13292 }
13293
13294 /*
13295 Skip Dfs Channel in case of P2P Search
13296 if it is set in ini file
13297 */
13298 if(cfg_param->skipDfsChnlInP2pSearch)
13299 {
13300 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013301 }
13302 else
13303 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013304 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013305 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013306
Agarwal Ashish4f616132013-12-30 23:32:50 +053013307 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013308 }
13309 }
13310
13311 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13312
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013313#ifdef FEATURE_WLAN_TDLS
13314 /* if tdls disagree scan right now, return immediately.
13315 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13316 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13317 */
13318 status = wlan_hdd_tdls_scan_callback (pAdapter,
13319 wiphy,
13320#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13321 dev,
13322#endif
13323 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013324 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013325 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053013326 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013327 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13328 "scan rejected %d", __func__, status);
13329 else
13330 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13331 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013332 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053013333 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013334 }
13335#endif
13336
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013337 /* acquire the wakelock to avoid the apps suspend during the scan. To
13338 * address the following issues.
13339 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13340 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13341 * for long time, this result in apps running at full power for long time.
13342 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13343 * be stuck in full power because of resume BMPS
13344 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013345 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013346
Nirav Shah20ac06f2013-12-12 18:14:06 +053013347 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13348 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013349 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13350 scanRequest.requestType, scanRequest.scanType,
13351 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013352 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13353
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013354 if (pHddCtx->spoofMacAddr.isEnabled &&
13355 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013356 {
13357 hddLog(VOS_TRACE_LEVEL_INFO,
13358 "%s: MAC Spoofing enabled for current scan", __func__);
13359 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13360 * to fill TxBds for probe request during current scan
13361 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013362 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013363 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013364
13365 if(status != VOS_STATUS_SUCCESS)
13366 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013367 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013368 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013369#ifdef FEATURE_WLAN_TDLS
13370 wlan_hdd_tdls_scan_done_callback(pAdapter);
13371#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013372 goto free_mem;
13373 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013374 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013375 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013376 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013377 pAdapter->sessionId, &scanRequest, &scanId,
13378 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013379
Jeff Johnson295189b2012-06-20 16:38:30 -070013380 if (eHAL_STATUS_SUCCESS != status)
13381 {
13382 hddLog(VOS_TRACE_LEVEL_ERROR,
13383 "%s: sme_ScanRequest returned error %d", __func__, status);
13384 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013385 if(eHAL_STATUS_RESOURCES == status)
13386 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013387 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13388 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013389 status = -EBUSY;
13390 } else {
13391 status = -EIO;
13392 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013393 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013394
13395#ifdef FEATURE_WLAN_TDLS
13396 wlan_hdd_tdls_scan_done_callback(pAdapter);
13397#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013398 goto free_mem;
13399 }
13400
13401 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013402 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013403 pAdapter->request = request;
13404 pScanInfo->scanId = scanId;
13405
13406 complete(&pScanInfo->scan_req_completion_event);
13407
13408free_mem:
13409 if( scanRequest.SSIDs.SSIDList )
13410 {
13411 vos_mem_free(scanRequest.SSIDs.SSIDList);
13412 }
13413
13414 if( channelList )
13415 vos_mem_free( channelList );
13416
13417 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013418 return status;
13419}
13420
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013421int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13422#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13423 struct net_device *dev,
13424#endif
13425 struct cfg80211_scan_request *request)
13426{
13427 int ret;
13428
13429 vos_ssr_protect(__func__);
13430 ret = __wlan_hdd_cfg80211_scan(wiphy,
13431#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13432 dev,
13433#endif
13434 request);
13435 vos_ssr_unprotect(__func__);
13436
13437 return ret;
13438}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013439
13440void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13441{
13442 v_U8_t iniDot11Mode =
13443 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13444 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13445
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013446 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13447 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013448 switch ( iniDot11Mode )
13449 {
13450 case eHDD_DOT11_MODE_AUTO:
13451 case eHDD_DOT11_MODE_11ac:
13452 case eHDD_DOT11_MODE_11ac_ONLY:
13453#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013454 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13455 sme_IsFeatureSupportedByFW(DOT11AC) )
13456 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13457 else
13458 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013459#else
13460 hddDot11Mode = eHDD_DOT11_MODE_11n;
13461#endif
13462 break;
13463 case eHDD_DOT11_MODE_11n:
13464 case eHDD_DOT11_MODE_11n_ONLY:
13465 hddDot11Mode = eHDD_DOT11_MODE_11n;
13466 break;
13467 default:
13468 hddDot11Mode = iniDot11Mode;
13469 break;
13470 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013471#ifdef WLAN_FEATURE_AP_HT40_24G
13472 if (operationChannel > SIR_11B_CHANNEL_END)
13473#endif
13474 {
13475 /* This call decides required channel bonding mode */
13476 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013477 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13478 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013479 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013480}
13481
Jeff Johnson295189b2012-06-20 16:38:30 -070013482/*
13483 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013484 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013485 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013486int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013487 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13488 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013489{
13490 int status = 0;
13491 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013492 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013493 v_U32_t roamId;
13494 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013495 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013496 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013497
13498 ENTER();
13499
13500 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013501 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13502
13503 status = wlan_hdd_validate_context(pHddCtx);
13504 if (status)
13505 {
Yue Mae36e3552014-03-05 17:06:20 -080013506 return status;
13507 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013508
Jeff Johnson295189b2012-06-20 16:38:30 -070013509 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13510 {
13511 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13512 return -EINVAL;
13513 }
13514
13515 pRoamProfile = &pWextState->roamProfile;
13516
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013517 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013518 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013519 hdd_station_ctx_t *pHddStaCtx;
13520 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013521
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013522 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13523
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013524 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013525 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13526 {
13527 /*QoS not enabled in cfg file*/
13528 pRoamProfile->uapsd_mask = 0;
13529 }
13530 else
13531 {
13532 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013533 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013534 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13535 }
13536
13537 pRoamProfile->SSIDs.numOfSSIDs = 1;
13538 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13539 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013540 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013541 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13542 ssid, ssid_len);
13543
13544 if (bssid)
13545 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013546 pValidBssid = bssid;
13547 }
13548 else if (bssid_hint)
13549 {
13550 pValidBssid = bssid_hint;
13551 }
13552 if (pValidBssid)
13553 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013554 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013555 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013556 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013557 /* Save BSSID in seperate variable as well, as RoamProfile
13558 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013559 case of join failure we should send valid BSSID to supplicant
13560 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013561 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013562 WNI_CFG_BSSID_LEN);
13563 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013564 else
13565 {
13566 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13567 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013568
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013569 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13570 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013571 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13572 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013573 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013574 /*set gen ie*/
13575 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13576 /*set auth*/
13577 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13578 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013579#ifdef FEATURE_WLAN_WAPI
13580 if (pAdapter->wapi_info.nWapiMode)
13581 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013582 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013583 switch (pAdapter->wapi_info.wapiAuthMode)
13584 {
13585 case WAPI_AUTH_MODE_PSK:
13586 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013587 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013588 pAdapter->wapi_info.wapiAuthMode);
13589 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13590 break;
13591 }
13592 case WAPI_AUTH_MODE_CERT:
13593 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013594 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013595 pAdapter->wapi_info.wapiAuthMode);
13596 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13597 break;
13598 }
13599 } // End of switch
13600 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13601 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13602 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013603 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013604 pRoamProfile->AuthType.numEntries = 1;
13605 pRoamProfile->EncryptionType.numEntries = 1;
13606 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13607 pRoamProfile->mcEncryptionType.numEntries = 1;
13608 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13609 }
13610 }
13611#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013612#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013613 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013614 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13615 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13616 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013617 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13618 sizeof (tSirGtkOffloadParams));
13619 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013620 }
13621#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013622 pRoamProfile->csrPersona = pAdapter->device_mode;
13623
Jeff Johnson32d95a32012-09-10 13:15:23 -070013624 if( operatingChannel )
13625 {
13626 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13627 pRoamProfile->ChannelInfo.numOfChannels = 1;
13628 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013629 else
13630 {
13631 pRoamProfile->ChannelInfo.ChannelList = NULL;
13632 pRoamProfile->ChannelInfo.numOfChannels = 0;
13633 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013634 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13635 {
13636 hdd_select_cbmode(pAdapter,operatingChannel);
13637 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013638
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013639 /*
13640 * Change conn_state to connecting before sme_RoamConnect(),
13641 * because sme_RoamConnect() has a direct path to call
13642 * hdd_smeRoamCallback(), which will change the conn_state
13643 * If direct path, conn_state will be accordingly changed
13644 * to NotConnected or Associated by either
13645 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13646 * in sme_RoamCallback()
13647 * if sme_RomConnect is to be queued,
13648 * Connecting state will remain until it is completed.
13649 * If connection state is not changed,
13650 * connection state will remain in eConnectionState_NotConnected state.
13651 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13652 * if conn state is eConnectionState_NotConnected.
13653 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13654 * informed of connect result indication which is an issue.
13655 */
13656
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013657 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13658 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013659 {
13660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013661 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013662 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13663 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013664 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013665 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013666 pAdapter->sessionId, pRoamProfile, &roamId);
13667
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013668 if ((eHAL_STATUS_SUCCESS != status) &&
13669 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13670 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013671
13672 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013673 hddLog(VOS_TRACE_LEVEL_ERROR,
13674 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13675 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013676 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013677 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013678 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013679 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013680
13681 pRoamProfile->ChannelInfo.ChannelList = NULL;
13682 pRoamProfile->ChannelInfo.numOfChannels = 0;
13683
Jeff Johnson295189b2012-06-20 16:38:30 -070013684 }
13685 else
13686 {
13687 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13688 return -EINVAL;
13689 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013690 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013691 return status;
13692}
13693
13694/*
13695 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
13696 * This function is used to set the authentication type (OPEN/SHARED).
13697 *
13698 */
13699static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
13700 enum nl80211_auth_type auth_type)
13701{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013702 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013703 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13704
13705 ENTER();
13706
13707 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013708 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070013709 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013710 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013711 hddLog(VOS_TRACE_LEVEL_INFO,
13712 "%s: set authentication type to AUTOSWITCH", __func__);
13713 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
13714 break;
13715
13716 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013717#ifdef WLAN_FEATURE_VOWIFI_11R
13718 case NL80211_AUTHTYPE_FT:
13719#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013720 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013721 "%s: set authentication type to OPEN", __func__);
13722 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
13723 break;
13724
13725 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013726 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013727 "%s: set authentication type to SHARED", __func__);
13728 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
13729 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013730#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013731 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013732 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013733 "%s: set authentication type to CCKM WPA", __func__);
13734 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
13735 break;
13736#endif
13737
13738
13739 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013740 hddLog(VOS_TRACE_LEVEL_ERROR,
13741 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013742 auth_type);
13743 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
13744 return -EINVAL;
13745 }
13746
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013747 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013748 pHddStaCtx->conn_info.authType;
13749 return 0;
13750}
13751
13752/*
13753 * FUNCTION: wlan_hdd_set_akm_suite
13754 * This function is used to set the key mgmt type(PSK/8021x).
13755 *
13756 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013757static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013758 u32 key_mgmt
13759 )
13760{
13761 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13762 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053013763 /* Should be in ieee802_11_defs.h */
13764#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
13765#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070013766 /*set key mgmt type*/
13767 switch(key_mgmt)
13768 {
13769 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053013770 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013771#ifdef WLAN_FEATURE_VOWIFI_11R
13772 case WLAN_AKM_SUITE_FT_PSK:
13773#endif
13774 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070013775 __func__);
13776 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
13777 break;
13778
13779 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053013780 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013781#ifdef WLAN_FEATURE_VOWIFI_11R
13782 case WLAN_AKM_SUITE_FT_8021X:
13783#endif
13784 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070013785 __func__);
13786 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13787 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013788#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013789#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
13790#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
13791 case WLAN_AKM_SUITE_CCKM:
13792 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
13793 __func__);
13794 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
13795 break;
13796#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070013797#ifndef WLAN_AKM_SUITE_OSEN
13798#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
13799 case WLAN_AKM_SUITE_OSEN:
13800 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
13801 __func__);
13802 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13803 break;
13804#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013805
13806 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013807 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013808 __func__, key_mgmt);
13809 return -EINVAL;
13810
13811 }
13812 return 0;
13813}
13814
13815/*
13816 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013817 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070013818 * (NONE/WEP40/WEP104/TKIP/CCMP).
13819 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013820static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
13821 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070013822 bool ucast
13823 )
13824{
13825 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013826 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013827 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13828
13829 ENTER();
13830
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013831 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013832 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013833 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070013834 __func__, cipher);
13835 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13836 }
13837 else
13838 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013839
Jeff Johnson295189b2012-06-20 16:38:30 -070013840 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013841 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013842 {
13843 case IW_AUTH_CIPHER_NONE:
13844 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13845 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013846
Jeff Johnson295189b2012-06-20 16:38:30 -070013847 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013848 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070013849 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013850
Jeff Johnson295189b2012-06-20 16:38:30 -070013851 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013852 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070013853 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013854
Jeff Johnson295189b2012-06-20 16:38:30 -070013855 case WLAN_CIPHER_SUITE_TKIP:
13856 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
13857 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013858
Jeff Johnson295189b2012-06-20 16:38:30 -070013859 case WLAN_CIPHER_SUITE_CCMP:
13860 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13861 break;
13862#ifdef FEATURE_WLAN_WAPI
13863 case WLAN_CIPHER_SUITE_SMS4:
13864 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
13865 break;
13866#endif
13867
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013868#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013869 case WLAN_CIPHER_SUITE_KRK:
13870 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
13871 break;
13872#endif
13873 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013874 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013875 __func__, cipher);
13876 return -EOPNOTSUPP;
13877 }
13878 }
13879
13880 if (ucast)
13881 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013882 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013883 __func__, encryptionType);
13884 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13885 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013886 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013887 encryptionType;
13888 }
13889 else
13890 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013891 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013892 __func__, encryptionType);
13893 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
13894 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
13895 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
13896 }
13897
13898 return 0;
13899}
13900
13901
13902/*
13903 * FUNCTION: wlan_hdd_cfg80211_set_ie
13904 * This function is used to parse WPA/RSN IE's.
13905 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013906int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013907#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13908 const u8 *ie,
13909#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013910 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013911#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013912 size_t ie_len
13913 )
13914{
13915 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013916#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13917 const u8 *genie = ie;
13918#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013919 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013920#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013921 v_U16_t remLen = ie_len;
13922#ifdef FEATURE_WLAN_WAPI
13923 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
13924 u16 *tmp;
13925 v_U16_t akmsuiteCount;
13926 int *akmlist;
13927#endif
13928 ENTER();
13929
13930 /* clear previous assocAddIE */
13931 pWextState->assocAddIE.length = 0;
13932 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013933 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013934
13935 while (remLen >= 2)
13936 {
13937 v_U16_t eLen = 0;
13938 v_U8_t elementId;
13939 elementId = *genie++;
13940 eLen = *genie++;
13941 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013942
Arif Hussain6d2a3322013-11-17 19:50:10 -080013943 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070013944 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013945
13946 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070013947 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013948 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013949 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 -070013950 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013951 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013952 "%s: Invalid WPA IE", __func__);
13953 return -EINVAL;
13954 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013955 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070013956 {
13957 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013958 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013959 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013960
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013961 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013962 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013963 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
13964 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013965 VOS_ASSERT(0);
13966 return -ENOMEM;
13967 }
13968 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13969 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13970 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013971
Jeff Johnson295189b2012-06-20 16:38:30 -070013972 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
13973 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13974 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13975 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013976 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
13977 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013978 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
13979 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
13980 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
13981 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
13982 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
13983 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013984 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053013985 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013986 {
13987 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013988 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013989 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013990
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013991 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013992 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013993 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13994 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013995 VOS_ASSERT(0);
13996 return -ENOMEM;
13997 }
13998 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13999 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14000 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014001
Jeff Johnson295189b2012-06-20 16:38:30 -070014002 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14003 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14004 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014005#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014006 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
14007 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014008 /*Consider WFD IE, only for P2P Client */
14009 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
14010 {
14011 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014012 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014013 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014014
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014015 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014016 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014017 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14018 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014019 VOS_ASSERT(0);
14020 return -ENOMEM;
14021 }
14022 // WFD IE is saved to Additional IE ; it should be accumulated to handle
14023 // WPS IE + P2P IE + WFD IE
14024 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14025 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014026
Jeff Johnson295189b2012-06-20 16:38:30 -070014027 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14028 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14029 }
14030#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014031 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014032 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014033 HS20_OUI_TYPE_SIZE)) )
14034 {
14035 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014036 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014037 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014038
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014039 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014040 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014041 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14042 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014043 VOS_ASSERT(0);
14044 return -ENOMEM;
14045 }
14046 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14047 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014048
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014049 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14050 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14051 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014052 /* Appending OSEN Information Element in Assiciation Request */
14053 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
14054 OSEN_OUI_TYPE_SIZE)) )
14055 {
14056 v_U16_t curAddIELen = pWextState->assocAddIE.length;
14057 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
14058 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014059
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014060 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014061 {
14062 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14063 "Need bigger buffer space");
14064 VOS_ASSERT(0);
14065 return -ENOMEM;
14066 }
14067 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14068 pWextState->assocAddIE.length += eLen + 2;
14069
14070 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
14071 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14072 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14073 }
14074
Abhishek Singh4322e622015-06-10 15:42:54 +053014075 /* Update only for WPA IE */
14076 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
14077 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014078
14079 /* populating as ADDIE in beacon frames */
14080 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014081 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014082 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
14083 {
14084 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14085 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
14086 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14087 {
14088 hddLog(LOGE,
14089 "Coldn't pass "
14090 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
14091 }
14092 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
14093 else
14094 hddLog(LOGE,
14095 "Could not pass on "
14096 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
14097
14098 /* IBSS mode doesn't contain params->proberesp_ies still
14099 beaconIE's need to be populated in probe response frames */
14100 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
14101 {
14102 u16 rem_probe_resp_ie_len = eLen + 2;
14103 u8 probe_rsp_ie_len[3] = {0};
14104 u8 counter = 0;
14105
14106 /* Check Probe Resp Length if it is greater then 255 then
14107 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
14108 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
14109 not able Store More then 255 bytes into One Variable */
14110
14111 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
14112 {
14113 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
14114 {
14115 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
14116 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
14117 }
14118 else
14119 {
14120 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
14121 rem_probe_resp_ie_len = 0;
14122 }
14123 }
14124
14125 rem_probe_resp_ie_len = 0;
14126
14127 if (probe_rsp_ie_len[0] > 0)
14128 {
14129 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14130 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
14131 (tANI_U8*)(genie - 2),
14132 probe_rsp_ie_len[0], NULL,
14133 eANI_BOOLEAN_FALSE)
14134 == eHAL_STATUS_FAILURE)
14135 {
14136 hddLog(LOGE,
14137 "Could not pass"
14138 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
14139 }
14140 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
14141 }
14142
14143 if (probe_rsp_ie_len[1] > 0)
14144 {
14145 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14146 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
14147 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14148 probe_rsp_ie_len[1], NULL,
14149 eANI_BOOLEAN_FALSE)
14150 == eHAL_STATUS_FAILURE)
14151 {
14152 hddLog(LOGE,
14153 "Could not pass"
14154 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14155 }
14156 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14157 }
14158
14159 if (probe_rsp_ie_len[2] > 0)
14160 {
14161 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14162 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14163 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14164 probe_rsp_ie_len[2], NULL,
14165 eANI_BOOLEAN_FALSE)
14166 == eHAL_STATUS_FAILURE)
14167 {
14168 hddLog(LOGE,
14169 "Could not pass"
14170 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14171 }
14172 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14173 }
14174
14175 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14176 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14177 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14178 {
14179 hddLog(LOGE,
14180 "Could not pass"
14181 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14182 }
14183 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014184 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014185 break;
14186 case DOT11F_EID_RSN:
14187 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14188 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14189 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14190 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14191 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14192 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014193
Abhishek Singhb16f3562016-01-20 11:08:32 +053014194 /* Appending extended capabilities with Interworking or
14195 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053014196 *
14197 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053014198 * interworkingService or bsstransition bit is set to 1.
14199 * Driver is only interested in interworkingService and
14200 * bsstransition capability from supplicant.
14201 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053014202 * required from supplicat, it needs to be handled while
14203 * sending Assoc Req in LIM.
14204 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014205 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014206 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014207 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014208 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014209 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014210
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014211 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014212 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014213 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14214 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014215 VOS_ASSERT(0);
14216 return -ENOMEM;
14217 }
14218 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14219 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014220
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014221 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14222 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14223 break;
14224 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014225#ifdef FEATURE_WLAN_WAPI
14226 case WLAN_EID_WAPI:
14227 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014228 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014229 pAdapter->wapi_info.nWapiMode);
14230 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014231 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014232 akmsuiteCount = WPA_GET_LE16(tmp);
14233 tmp = tmp + 1;
14234 akmlist = (int *)(tmp);
14235 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14236 {
14237 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14238 }
14239 else
14240 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014241 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014242 VOS_ASSERT(0);
14243 return -EINVAL;
14244 }
14245
14246 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14247 {
14248 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014249 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014250 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014251 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014252 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014253 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014254 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014255 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014256 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14257 }
14258 break;
14259#endif
14260 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014261 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014262 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014263 /* when Unknown IE is received we should break and continue
14264 * to the next IE in the buffer instead we were returning
14265 * so changing this to break */
14266 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014267 }
14268 genie += eLen;
14269 remLen -= eLen;
14270 }
14271 EXIT();
14272 return 0;
14273}
14274
14275/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014276 * FUNCTION: hdd_isWPAIEPresent
14277 * Parse the received IE to find the WPA IE
14278 *
14279 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014280static bool hdd_isWPAIEPresent(
14281#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14282 const u8 *ie,
14283#else
14284 u8 *ie,
14285#endif
14286 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014287{
14288 v_U8_t eLen = 0;
14289 v_U16_t remLen = ie_len;
14290 v_U8_t elementId = 0;
14291
14292 while (remLen >= 2)
14293 {
14294 elementId = *ie++;
14295 eLen = *ie++;
14296 remLen -= 2;
14297 if (eLen > remLen)
14298 {
14299 hddLog(VOS_TRACE_LEVEL_ERROR,
14300 "%s: IE length is wrong %d", __func__, eLen);
14301 return FALSE;
14302 }
14303 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14304 {
14305 /* OUI - 0x00 0X50 0XF2
14306 WPA Information Element - 0x01
14307 WPA version - 0x01*/
14308 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14309 return TRUE;
14310 }
14311 ie += eLen;
14312 remLen -= eLen;
14313 }
14314 return FALSE;
14315}
14316
14317/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014318 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014319 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014320 * parameters during connect operation.
14321 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014322int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014323 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014324 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014325{
14326 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014327 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014328 ENTER();
14329
14330 /*set wpa version*/
14331 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14332
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014333 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014334 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014335 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014336 {
14337 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14338 }
14339 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14340 {
14341 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14342 }
14343 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014344
14345 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014346 pWextState->wpaVersion);
14347
14348 /*set authentication type*/
14349 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14350
14351 if (0 > status)
14352 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014353 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014354 "%s: failed to set authentication type ", __func__);
14355 return status;
14356 }
14357
14358 /*set key mgmt type*/
14359 if (req->crypto.n_akm_suites)
14360 {
14361 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14362 if (0 > status)
14363 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014364 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014365 __func__);
14366 return status;
14367 }
14368 }
14369
14370 /*set pairwise cipher type*/
14371 if (req->crypto.n_ciphers_pairwise)
14372 {
14373 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14374 req->crypto.ciphers_pairwise[0], true);
14375 if (0 > status)
14376 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014377 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014378 "%s: failed to set unicast cipher type", __func__);
14379 return status;
14380 }
14381 }
14382 else
14383 {
14384 /*Reset previous cipher suite to none*/
14385 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14386 if (0 > status)
14387 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014388 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014389 "%s: failed to set unicast cipher type", __func__);
14390 return status;
14391 }
14392 }
14393
14394 /*set group cipher type*/
14395 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14396 false);
14397
14398 if (0 > status)
14399 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014400 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014401 __func__);
14402 return status;
14403 }
14404
Chet Lanctot186b5732013-03-18 10:26:30 -070014405#ifdef WLAN_FEATURE_11W
14406 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14407#endif
14408
Jeff Johnson295189b2012-06-20 16:38:30 -070014409 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14410 if (req->ie_len)
14411 {
14412 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14413 if ( 0 > status)
14414 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014415 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014416 __func__);
14417 return status;
14418 }
14419 }
14420
14421 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014422 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014423 {
14424 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14425 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14426 )
14427 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014428 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014429 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14430 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014431 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014432 __func__);
14433 return -EOPNOTSUPP;
14434 }
14435 else
14436 {
14437 u8 key_len = req->key_len;
14438 u8 key_idx = req->key_idx;
14439
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014440 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014441 && (CSR_MAX_NUM_KEY > key_idx)
14442 )
14443 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014444 hddLog(VOS_TRACE_LEVEL_INFO,
14445 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014446 __func__, key_idx, key_len);
14447 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014448 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014449 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014450 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014451 (u8)key_len;
14452 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14453 }
14454 }
14455 }
14456 }
14457
14458 return status;
14459}
14460
14461/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014462 * FUNCTION: wlan_hdd_try_disconnect
14463 * This function is used to disconnect from previous
14464 * connection
14465 */
14466static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14467{
14468 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014469 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014470 hdd_station_ctx_t *pHddStaCtx;
14471 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014472 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014473
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014474 ret = wlan_hdd_validate_context(pHddCtx);
14475 if (0 != ret)
14476 {
14477 return ret;
14478 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014479 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14480
14481 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14482
14483 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14484 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053014485 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014486 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14487 {
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014488 spin_lock_bh(&pAdapter->lock_for_active_session);
14489 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14490 {
14491 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14492 }
14493 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053014494 hdd_connSetConnectionState(pHddStaCtx,
14495 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014496 /* Issue disconnect to CSR */
14497 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014498 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014499 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014500 eCSR_DISCONNECT_REASON_UNSPECIFIED);
14501 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
14502 hddLog(LOG1,
14503 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
14504 } else if ( 0 != status ) {
14505 hddLog(LOGE,
14506 FL("csrRoamDisconnect failure, returned %d"),
14507 (int)status );
14508 result = -EINVAL;
14509 goto disconnected;
14510 }
14511 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014512 &pAdapter->disconnect_comp_var,
14513 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014514 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
14515 hddLog(LOGE,
14516 "%s: Failed to disconnect, timed out", __func__);
14517 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014518 }
14519 }
14520 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14521 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014522 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014523 &pAdapter->disconnect_comp_var,
14524 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014525 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014526 {
14527 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014528 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014529 }
14530 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014531disconnected:
14532 hddLog(LOG1,
14533 FL("Set HDD connState to eConnectionState_NotConnected"));
14534 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14535 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014536}
14537
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014538/**
14539 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
14540 * @adapter: Pointer to the HDD adapter
14541 * @req: Pointer to the structure cfg_connect_params receieved from user space
14542 *
14543 * This function will start reassociation if bssid hint, channel hint and
14544 * previous bssid parameters are present in the connect request
14545 *
14546 * Return: success if reassociation is happening
14547 * Error code if reassociation is not permitted or not happening
14548 */
14549#ifdef CFG80211_CONNECT_PREV_BSSID
14550static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14551 struct cfg80211_connect_params *req)
14552{
14553 int status = -EPERM;
14554 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
14555 hddLog(VOS_TRACE_LEVEL_INFO,
14556 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
14557 req->channel_hint->hw_value,
14558 MAC_ADDR_ARRAY(req->bssid_hint));
14559 status = hdd_reassoc(adapter, req->bssid_hint,
14560 req->channel_hint->hw_value,
14561 CONNECT_CMD_USERSPACE);
14562 }
14563 return status;
14564}
14565#else
14566static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14567 struct cfg80211_connect_params *req)
14568{
14569 return -EPERM;
14570}
14571#endif
14572
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014573/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014574 * FUNCTION: __wlan_hdd_cfg80211_connect
14575 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014576 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014577static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014578 struct net_device *ndev,
14579 struct cfg80211_connect_params *req
14580 )
14581{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014582 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014583 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053014584#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
14585 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014586 const u8 *bssid_hint = req->bssid_hint;
14587#else
14588 const u8 *bssid_hint = NULL;
14589#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014590 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014591 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014592 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014593
14594 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014595
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014596 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14597 TRACE_CODE_HDD_CFG80211_CONNECT,
14598 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014599 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014600 "%s: device_mode = %s (%d)", __func__,
14601 hdd_device_modetoString(pAdapter->device_mode),
14602 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014603
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014604 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014605 if (!pHddCtx)
14606 {
14607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14608 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014609 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014610 }
14611
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014612 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014613 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014614 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014615 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014616 }
14617
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014618 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
14619 if (0 == status)
14620 return status;
14621
Agarwal Ashish51325b52014-06-16 16:50:49 +053014622
Jeff Johnson295189b2012-06-20 16:38:30 -070014623#ifdef WLAN_BTAMP_FEATURE
14624 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014625 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014626 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014627 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014628 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014629 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014630 }
14631#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014632
14633 //If Device Mode is Station Concurrent Sessions Exit BMps
14634 //P2P Mode will be taken care in Open/close adapter
14635 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014636 (vos_concurrent_open_sessions_running())) {
14637 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14638 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014639 }
14640
14641 /*Try disconnecting if already in connected state*/
14642 status = wlan_hdd_try_disconnect(pAdapter);
14643 if ( 0 > status)
14644 {
14645 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14646 " connection"));
14647 return -EALREADY;
14648 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053014649 /* Check for max concurrent connections after doing disconnect if any*/
14650 if (vos_max_concurrent_connections_reached()) {
14651 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14652 return -ECONNREFUSED;
14653 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014654
Jeff Johnson295189b2012-06-20 16:38:30 -070014655 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014656 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014657
14658 if ( 0 > status)
14659 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014660 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014661 __func__);
14662 return status;
14663 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053014664
14665 if (pHddCtx->spoofMacAddr.isEnabled)
14666 {
14667 hddLog(VOS_TRACE_LEVEL_INFO,
14668 "%s: MAC Spoofing enabled ", __func__);
14669 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14670 * to fill TxBds for probe request during SSID scan which may happen
14671 * as part of connect command
14672 */
14673 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
14674 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
14675 if (status != VOS_STATUS_SUCCESS)
14676 return -ECONNREFUSED;
14677 }
14678
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014679 if (req->channel)
14680 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070014681 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014682 channel = 0;
14683 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14684 req->ssid_len, req->bssid,
14685 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014686
Sushant Kaushikd7083982015-03-18 14:33:24 +053014687 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014688 {
14689 //ReEnable BMPS if disabled
14690 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
14691 (NULL != pHddCtx))
14692 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053014693 if (pHddCtx->hdd_wlan_suspended)
14694 {
14695 hdd_set_pwrparams(pHddCtx);
14696 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014697 //ReEnable Bmps and Imps back
14698 hdd_enable_bmps_imps(pHddCtx);
14699 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014700 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070014701 return status;
14702 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014703 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014704 EXIT();
14705 return status;
14706}
14707
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014708static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
14709 struct net_device *ndev,
14710 struct cfg80211_connect_params *req)
14711{
14712 int ret;
14713 vos_ssr_protect(__func__);
14714 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
14715 vos_ssr_unprotect(__func__);
14716
14717 return ret;
14718}
Jeff Johnson295189b2012-06-20 16:38:30 -070014719
14720/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014721 * FUNCTION: wlan_hdd_disconnect
14722 * This function is used to issue a disconnect request to SME
14723 */
14724int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
14725{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014726 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014727 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014728 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014729 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014730
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014731 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014732
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014733 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014734 if (0 != status)
14735 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014736 return status;
14737 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053014738 /* Indicate sme of disconnect so that in progress connection or preauth
14739 * can be aborted
14740 */
14741 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053014742 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014743 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014744
Agarwal Ashish47d18112014-08-04 19:55:07 +053014745 /* Need to apply spin lock before decreasing active sessions
14746 * as there can be chance for double decrement if context switch
14747 * Calls hdd_DisConnectHandler.
14748 */
14749
14750 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014751 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14752 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014753 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14754 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053014755 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
14756 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014757
Abhishek Singhf4669da2014-05-26 15:07:49 +053014758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053014759 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
14760
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014761 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014762
Mihir Shete182a0b22014-08-18 16:08:48 +053014763 /*
14764 * stop tx queues before deleting STA/BSS context from the firmware.
14765 * tx has to be disabled because the firmware can get busy dropping
14766 * the tx frames after BSS/STA has been deleted and will not send
14767 * back a response resulting in WDI timeout
14768 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053014769 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053014770 netif_tx_disable(pAdapter->dev);
14771 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014772
Mihir Shete182a0b22014-08-18 16:08:48 +053014773 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014774 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14775 pAdapter->sessionId, reason);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014776 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
14777 {
14778 hddLog(LOG1,
14779 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014780 }
14781 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014782 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014783 hddLog(LOGE,
14784 FL("csrRoamDisconnect failure, returned %d"),
14785 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014786 result = -EINVAL;
14787 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014788 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014789 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014790 &pAdapter->disconnect_comp_var,
14791 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014792 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014793 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014794 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014795 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014796 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014797 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014798disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014799 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014800 FL("Set HDD connState to eConnectionState_NotConnected"));
14801 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053014802#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
14803 /* Sending disconnect event to userspace for kernel version < 3.11
14804 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
14805 */
14806 hddLog(LOG1, FL("Send disconnected event to userspace"));
14807
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053014808 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053014809 WLAN_REASON_UNSPECIFIED);
14810#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014811
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014812 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014813 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014814}
14815
14816
14817/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014818 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070014819 * This function is used to issue a disconnect request to SME
14820 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014821static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014822 struct net_device *dev,
14823 u16 reason
14824 )
14825{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014826 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014827 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014828 tCsrRoamProfile *pRoamProfile;
14829 hdd_station_ctx_t *pHddStaCtx;
14830 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014831#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014832 tANI_U8 staIdx;
14833#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014834
Jeff Johnson295189b2012-06-20 16:38:30 -070014835 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014836
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014837 if (!pAdapter) {
14838 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14839 return -EINVAL;
14840 }
14841
14842 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14843 if (!pHddStaCtx) {
14844 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
14845 return -EINVAL;
14846 }
14847
14848 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14849 status = wlan_hdd_validate_context(pHddCtx);
14850 if (0 != status)
14851 {
14852 return status;
14853 }
14854
14855 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
14856
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014857 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14858 TRACE_CODE_HDD_CFG80211_DISCONNECT,
14859 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014860 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
14861 __func__, hdd_device_modetoString(pAdapter->device_mode),
14862 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014863
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014864 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
14865 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070014866
Jeff Johnson295189b2012-06-20 16:38:30 -070014867 if (NULL != pRoamProfile)
14868 {
14869 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014870 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
14871 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070014872 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014873 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070014874 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014875 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014876 switch(reason)
14877 {
14878 case WLAN_REASON_MIC_FAILURE:
14879 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
14880 break;
14881
14882 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
14883 case WLAN_REASON_DISASSOC_AP_BUSY:
14884 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
14885 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
14886 break;
14887
14888 case WLAN_REASON_PREV_AUTH_NOT_VALID:
14889 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053014890 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070014891 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
14892 break;
14893
Jeff Johnson295189b2012-06-20 16:38:30 -070014894 default:
14895 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
14896 break;
14897 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014898 pScanInfo = &pHddCtx->scan_info;
14899 if (pScanInfo->mScanPending)
14900 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014901 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014902 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014903 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014904 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014905 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053014906 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014907#ifdef FEATURE_WLAN_TDLS
14908 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014909 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014910 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014911 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
14912 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014913 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014914 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014915 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014916 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014917 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014918 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014919 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014920 status = sme_DeleteTdlsPeerSta(
14921 WLAN_HDD_GET_HAL_CTX(pAdapter),
14922 pAdapter->sessionId,
14923 mac);
14924 if (status != eHAL_STATUS_SUCCESS) {
14925 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
14926 return -EPERM;
14927 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014928 }
14929 }
14930#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014931 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014932 status = wlan_hdd_disconnect(pAdapter, reasonCode);
14933 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070014934 {
14935 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014936 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014937 __func__, (int)status );
14938 return -EINVAL;
14939 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014940 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014941 else
14942 {
14943 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
14944 "called while in %d state", __func__,
14945 pHddStaCtx->conn_info.connState);
14946 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014947 }
14948 else
14949 {
14950 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
14951 }
14952
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014953 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014954 return status;
14955}
14956
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014957static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
14958 struct net_device *dev,
14959 u16 reason
14960 )
14961{
14962 int ret;
14963 vos_ssr_protect(__func__);
14964 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
14965 vos_ssr_unprotect(__func__);
14966
14967 return ret;
14968}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014969
Jeff Johnson295189b2012-06-20 16:38:30 -070014970/*
14971 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014972 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014973 * settings in IBSS mode.
14974 */
14975static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014976 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014977 struct cfg80211_ibss_params *params
14978 )
14979{
14980 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014981 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014982 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14983 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014984
Jeff Johnson295189b2012-06-20 16:38:30 -070014985 ENTER();
14986
14987 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070014988 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070014989
14990 if (params->ie_len && ( NULL != params->ie) )
14991 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014992 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14993 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014994 {
14995 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14996 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14997 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014998 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014999 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015000 tDot11fIEWPA dot11WPAIE;
15001 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015002 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015003
Wilson Yang00256342013-10-10 23:13:38 -070015004 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015005 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15006 params->ie_len, DOT11F_EID_WPA);
15007 if ( NULL != ie )
15008 {
15009 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15010 // Unpack the WPA IE
15011 //Skip past the EID byte and length byte - and four byte WiFi OUI
15012 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
15013 &ie[2+4],
15014 ie[1] - 4,
15015 &dot11WPAIE);
15016 /*Extract the multicast cipher, the encType for unicast
15017 cipher for wpa-none is none*/
15018 encryptionType =
15019 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
15020 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015021 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015022
Jeff Johnson295189b2012-06-20 16:38:30 -070015023 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
15024
15025 if (0 > status)
15026 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015027 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015028 __func__);
15029 return status;
15030 }
15031 }
15032
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015033 pWextState->roamProfile.AuthType.authType[0] =
15034 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070015035 eCSR_AUTH_TYPE_OPEN_SYSTEM;
15036
15037 if (params->privacy)
15038 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015039 /* Security enabled IBSS, At this time there is no information available
15040 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070015041 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015042 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070015043 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015044 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070015045 *enable privacy bit in beacons */
15046
15047 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
15048 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015049 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
15050 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070015051 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15052 pWextState->roamProfile.EncryptionType.numEntries = 1;
15053 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070015054 return status;
15055}
15056
15057/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015058 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015059 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015060 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015061static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015062 struct net_device *dev,
15063 struct cfg80211_ibss_params *params
15064 )
15065{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015066 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015067 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15068 tCsrRoamProfile *pRoamProfile;
15069 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015070 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15071 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015072 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070015073
15074 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015075
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015076 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15077 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
15078 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015079 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015080 "%s: device_mode = %s (%d)", __func__,
15081 hdd_device_modetoString(pAdapter->device_mode),
15082 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015083
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015084 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015085 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015086 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015087 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015088 }
15089
15090 if (NULL == pWextState)
15091 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015092 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015093 __func__);
15094 return -EIO;
15095 }
15096
Agarwal Ashish51325b52014-06-16 16:50:49 +053015097 if (vos_max_concurrent_connections_reached()) {
15098 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15099 return -ECONNREFUSED;
15100 }
15101
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015102 /*Try disconnecting if already in connected state*/
15103 status = wlan_hdd_try_disconnect(pAdapter);
15104 if ( 0 > status)
15105 {
15106 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15107 " IBSS connection"));
15108 return -EALREADY;
15109 }
15110
Jeff Johnson295189b2012-06-20 16:38:30 -070015111 pRoamProfile = &pWextState->roamProfile;
15112
15113 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
15114 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015115 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015116 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015117 return -EINVAL;
15118 }
15119
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015120 /* BSSID is provided by upper layers hence no need to AUTO generate */
15121 if (NULL != params->bssid) {
15122 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15123 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
15124 hddLog (VOS_TRACE_LEVEL_ERROR,
15125 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15126 return -EIO;
15127 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015128 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015129 }
krunal sonie9002db2013-11-25 14:24:17 -080015130 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
15131 {
15132 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15133 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
15134 {
15135 hddLog (VOS_TRACE_LEVEL_ERROR,
15136 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15137 return -EIO;
15138 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015139
15140 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080015141 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015142 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080015143 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015144
Jeff Johnson295189b2012-06-20 16:38:30 -070015145 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070015146 if (NULL !=
15147#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15148 params->chandef.chan)
15149#else
15150 params->channel)
15151#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015152 {
15153 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015154 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15155 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
15156 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15157 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015158
15159 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015160 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070015161 ieee80211_frequency_to_channel(
15162#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15163 params->chandef.chan->center_freq);
15164#else
15165 params->channel->center_freq);
15166#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015167
15168 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15169 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070015170 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015171 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
15172 __func__);
15173 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070015174 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015175
15176 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015177 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015178 if (channelNum == validChan[indx])
15179 {
15180 break;
15181 }
15182 }
15183 if (indx >= numChans)
15184 {
15185 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015186 __func__, channelNum);
15187 return -EINVAL;
15188 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015189 /* Set the Operational Channel */
15190 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
15191 channelNum);
15192 pRoamProfile->ChannelInfo.numOfChannels = 1;
15193 pHddStaCtx->conn_info.operationChannel = channelNum;
15194 pRoamProfile->ChannelInfo.ChannelList =
15195 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070015196 }
15197
15198 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015199 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070015200 if (status < 0)
15201 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015202 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070015203 __func__);
15204 return status;
15205 }
15206
15207 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015208 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053015209 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015210 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015211
15212 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015213 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015214
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015215 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015216 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015217}
15218
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015219static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
15220 struct net_device *dev,
15221 struct cfg80211_ibss_params *params
15222 )
15223{
15224 int ret = 0;
15225
15226 vos_ssr_protect(__func__);
15227 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15228 vos_ssr_unprotect(__func__);
15229
15230 return ret;
15231}
15232
Jeff Johnson295189b2012-06-20 16:38:30 -070015233/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015234 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015235 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015236 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015237static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015238 struct net_device *dev
15239 )
15240{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015241 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015242 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15243 tCsrRoamProfile *pRoamProfile;
15244 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015245 int status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015246#ifdef WLAN_FEATURE_RMC
15247 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
15248#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015249
15250 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015251
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015252 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15253 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15254 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015255 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015256 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015257 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015258 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015259 }
15260
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015261 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15262 hdd_device_modetoString(pAdapter->device_mode),
15263 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015264 if (NULL == pWextState)
15265 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015266 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015267 __func__);
15268 return -EIO;
15269 }
15270
15271 pRoamProfile = &pWextState->roamProfile;
15272
15273 /* Issue disconnect only if interface type is set to IBSS */
15274 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15275 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015276 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015277 __func__);
15278 return -EINVAL;
15279 }
15280
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015281#ifdef WLAN_FEATURE_RMC
15282 /* Clearing add IE of beacon */
15283 if (ccmCfgSetStr(pHddCtx->hHal,
15284 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
15285 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
15286 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15287 {
15288 hddLog (VOS_TRACE_LEVEL_ERROR,
15289 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
15290 return -EINVAL;
15291 }
15292 if (ccmCfgSetInt(pHddCtx->hHal,
15293 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
15294 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15295 {
15296 hddLog (VOS_TRACE_LEVEL_ERROR,
15297 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
15298 __func__);
15299 return -EINVAL;
15300 }
15301
15302 // Reset WNI_CFG_PROBE_RSP Flags
15303 wlan_hdd_reset_prob_rspies(pAdapter);
15304
15305 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15306 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
15307 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15308 {
15309 hddLog (VOS_TRACE_LEVEL_ERROR,
15310 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
15311 __func__);
15312 return -EINVAL;
15313 }
15314#endif
15315
Jeff Johnson295189b2012-06-20 16:38:30 -070015316 /* Issue Disconnect request */
15317 INIT_COMPLETION(pAdapter->disconnect_comp_var);
15318 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15319 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15320
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015321 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015322 return 0;
15323}
15324
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015325static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15326 struct net_device *dev
15327 )
15328{
15329 int ret = 0;
15330
15331 vos_ssr_protect(__func__);
15332 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15333 vos_ssr_unprotect(__func__);
15334
15335 return ret;
15336}
15337
Jeff Johnson295189b2012-06-20 16:38:30 -070015338/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015339 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015340 * This function is used to set the phy parameters
15341 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15342 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015343static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015344 u32 changed)
15345{
15346 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15347 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015348 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015349
15350 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015351
15352 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015353 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15354 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015355
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015356 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015357 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015358 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015359 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015360 }
15361
Jeff Johnson295189b2012-06-20 16:38:30 -070015362 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15363 {
15364 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15365 WNI_CFG_RTS_THRESHOLD_STAMAX :
15366 wiphy->rts_threshold;
15367
15368 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015369 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015370 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015371 hddLog(VOS_TRACE_LEVEL_ERROR,
15372 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015373 __func__, rts_threshold);
15374 return -EINVAL;
15375 }
15376
15377 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15378 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015379 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015380 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015381 hddLog(VOS_TRACE_LEVEL_ERROR,
15382 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015383 __func__, rts_threshold);
15384 return -EIO;
15385 }
15386
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015387 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015388 rts_threshold);
15389 }
15390
15391 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15392 {
15393 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15394 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15395 wiphy->frag_threshold;
15396
15397 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015398 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015399 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015400 hddLog(VOS_TRACE_LEVEL_ERROR,
15401 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015402 frag_threshold);
15403 return -EINVAL;
15404 }
15405
15406 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15407 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015408 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015409 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015410 hddLog(VOS_TRACE_LEVEL_ERROR,
15411 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015412 __func__, frag_threshold);
15413 return -EIO;
15414 }
15415
15416 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15417 frag_threshold);
15418 }
15419
15420 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15421 || (changed & WIPHY_PARAM_RETRY_LONG))
15422 {
15423 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15424 wiphy->retry_short :
15425 wiphy->retry_long;
15426
15427 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15428 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15429 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015430 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015431 __func__, retry_value);
15432 return -EINVAL;
15433 }
15434
15435 if (changed & WIPHY_PARAM_RETRY_SHORT)
15436 {
15437 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15438 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015439 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015440 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015441 hddLog(VOS_TRACE_LEVEL_ERROR,
15442 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015443 __func__, retry_value);
15444 return -EIO;
15445 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015446 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015447 __func__, retry_value);
15448 }
15449 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15450 {
15451 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15452 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015453 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015454 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015455 hddLog(VOS_TRACE_LEVEL_ERROR,
15456 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015457 __func__, retry_value);
15458 return -EIO;
15459 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015460 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015461 __func__, retry_value);
15462 }
15463 }
15464
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015465 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015466 return 0;
15467}
15468
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015469static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15470 u32 changed)
15471{
15472 int ret;
15473
15474 vos_ssr_protect(__func__);
15475 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15476 vos_ssr_unprotect(__func__);
15477
15478 return ret;
15479}
15480
Jeff Johnson295189b2012-06-20 16:38:30 -070015481/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015482 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015483 * This function is used to set the txpower
15484 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015485static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015486#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15487 struct wireless_dev *wdev,
15488#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015489#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015490 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015491#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015492 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015493#endif
15494 int dbm)
15495{
15496 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015497 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015498 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15499 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015500 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015501
15502 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015503
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015504 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15505 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15506 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015507 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015508 if (0 != status)
15509 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015510 return status;
15511 }
15512
15513 hHal = pHddCtx->hHal;
15514
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015515 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15516 dbm, ccmCfgSetCallback,
15517 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015518 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015519 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015520 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15521 return -EIO;
15522 }
15523
15524 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15525 dbm);
15526
15527 switch(type)
15528 {
15529 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15530 /* Fall through */
15531 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15532 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15533 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015534 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15535 __func__);
15536 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015537 }
15538 break;
15539 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015540 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015541 __func__);
15542 return -EOPNOTSUPP;
15543 break;
15544 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015545 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15546 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015547 return -EIO;
15548 }
15549
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015550 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015551 return 0;
15552}
15553
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015554static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15555#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15556 struct wireless_dev *wdev,
15557#endif
15558#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15559 enum tx_power_setting type,
15560#else
15561 enum nl80211_tx_power_setting type,
15562#endif
15563 int dbm)
15564{
15565 int ret;
15566 vos_ssr_protect(__func__);
15567 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15568#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15569 wdev,
15570#endif
15571#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15572 type,
15573#else
15574 type,
15575#endif
15576 dbm);
15577 vos_ssr_unprotect(__func__);
15578
15579 return ret;
15580}
15581
Jeff Johnson295189b2012-06-20 16:38:30 -070015582/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015583 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015584 * This function is used to read the txpower
15585 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015586static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015587#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15588 struct wireless_dev *wdev,
15589#endif
15590 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015591{
15592
15593 hdd_adapter_t *pAdapter;
15594 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015595 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015596
Jeff Johnsone7245742012-09-05 17:12:55 -070015597 ENTER();
15598
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015599 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015600 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015601 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015602 *dbm = 0;
15603 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015604 }
15605
Jeff Johnson295189b2012-06-20 16:38:30 -070015606 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15607 if (NULL == pAdapter)
15608 {
15609 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15610 return -ENOENT;
15611 }
15612
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015613 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15614 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15615 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015616 wlan_hdd_get_classAstats(pAdapter);
15617 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15618
Jeff Johnsone7245742012-09-05 17:12:55 -070015619 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015620 return 0;
15621}
15622
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015623static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15624#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15625 struct wireless_dev *wdev,
15626#endif
15627 int *dbm)
15628{
15629 int ret;
15630
15631 vos_ssr_protect(__func__);
15632 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15633#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15634 wdev,
15635#endif
15636 dbm);
15637 vos_ssr_unprotect(__func__);
15638
15639 return ret;
15640}
15641
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015642static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015643#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15644 const u8* mac,
15645#else
15646 u8* mac,
15647#endif
15648 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015649{
15650 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15651 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15652 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053015653 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015654
15655 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
15656 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070015657
15658 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
15659 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
15660 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
15661 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
15662 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
15663 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
15664 tANI_U16 maxRate = 0;
15665 tANI_U16 myRate;
15666 tANI_U16 currentRate = 0;
15667 tANI_U8 maxSpeedMCS = 0;
15668 tANI_U8 maxMCSIdx = 0;
15669 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053015670 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070015671 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015672 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015673
Leo Chang6f8870f2013-03-26 18:11:36 -070015674#ifdef WLAN_FEATURE_11AC
15675 tANI_U32 vht_mcs_map;
15676 eDataRate11ACMaxMcs vhtMaxMcs;
15677#endif /* WLAN_FEATURE_11AC */
15678
Jeff Johnsone7245742012-09-05 17:12:55 -070015679 ENTER();
15680
Jeff Johnson295189b2012-06-20 16:38:30 -070015681 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15682 (0 == ssidlen))
15683 {
15684 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
15685 " Invalid ssidlen, %d", __func__, ssidlen);
15686 /*To keep GUI happy*/
15687 return 0;
15688 }
15689
Mukul Sharma811205f2014-07-09 21:07:30 +053015690 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
15691 {
15692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15693 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053015694 /* return a cached value */
15695 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053015696 return 0;
15697 }
15698
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015699 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015700 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015701 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015702 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015703 }
15704
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053015705 wlan_hdd_get_station_stats(pAdapter);
15706 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015707
Kiet Lam3b17fc82013-09-27 05:24:08 +053015708 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
15709 sinfo->filled |= STATION_INFO_SIGNAL;
15710
c_hpothu09f19542014-05-30 21:53:31 +053015711 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053015712 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
15713 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053015714 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053015715 {
15716 rate_flags = pAdapter->maxRateFlags;
15717 }
c_hpothu44ff4e02014-05-08 00:13:57 +053015718
Jeff Johnson295189b2012-06-20 16:38:30 -070015719 //convert to the UI units of 100kbps
15720 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
15721
15722#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070015723 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 -070015724 sinfo->signal,
15725 pCfg->reportMaxLinkSpeed,
15726 myRate,
15727 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015728 (int) pCfg->linkSpeedRssiMid,
15729 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070015730 (int) rate_flags,
15731 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070015732#endif //LINKSPEED_DEBUG_ENABLED
15733
15734 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
15735 {
15736 // we do not want to necessarily report the current speed
15737 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
15738 {
15739 // report the max possible speed
15740 rssidx = 0;
15741 }
15742 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
15743 {
15744 // report the max possible speed with RSSI scaling
15745 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
15746 {
15747 // report the max possible speed
15748 rssidx = 0;
15749 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015750 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070015751 {
15752 // report middle speed
15753 rssidx = 1;
15754 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015755 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
15756 {
15757 // report middle speed
15758 rssidx = 2;
15759 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015760 else
15761 {
15762 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015763 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070015764 }
15765 }
15766 else
15767 {
15768 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
15769 hddLog(VOS_TRACE_LEVEL_ERROR,
15770 "%s: Invalid value for reportMaxLinkSpeed: %u",
15771 __func__, pCfg->reportMaxLinkSpeed);
15772 rssidx = 0;
15773 }
15774
15775 maxRate = 0;
15776
15777 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015778 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
15779 OperationalRates, &ORLeng))
15780 {
15781 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15782 /*To keep GUI happy*/
15783 return 0;
15784 }
15785
Jeff Johnson295189b2012-06-20 16:38:30 -070015786 for (i = 0; i < ORLeng; i++)
15787 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015788 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015789 {
15790 /* Validate Rate Set */
15791 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
15792 {
15793 currentRate = supported_data_rate[j].supported_rate[rssidx];
15794 break;
15795 }
15796 }
15797 /* Update MAX rate */
15798 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15799 }
15800
15801 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015802 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
15803 ExtendedRates, &ERLeng))
15804 {
15805 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15806 /*To keep GUI happy*/
15807 return 0;
15808 }
15809
Jeff Johnson295189b2012-06-20 16:38:30 -070015810 for (i = 0; i < ERLeng; i++)
15811 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015812 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015813 {
15814 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
15815 {
15816 currentRate = supported_data_rate[j].supported_rate[rssidx];
15817 break;
15818 }
15819 }
15820 /* Update MAX rate */
15821 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15822 }
c_hpothu79aab322014-07-14 21:11:01 +053015823
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015824 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053015825 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015826 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053015827 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070015828 {
c_hpothu79aab322014-07-14 21:11:01 +053015829 if (rate_flags & eHAL_TX_RATE_VHT80)
15830 mode = 2;
15831 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
15832 mode = 1;
15833 else
15834 mode = 0;
15835
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015836 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
15837 MCSRates, &MCSLeng))
15838 {
15839 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15840 /*To keep GUI happy*/
15841 return 0;
15842 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015843 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070015844#ifdef WLAN_FEATURE_11AC
15845 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015846 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070015847 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015848 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015849 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070015850 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070015851 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015852 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015853 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015854 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070015855 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015856 maxMCSIdx = 7;
15857 }
15858 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
15859 {
15860 maxMCSIdx = 8;
15861 }
15862 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
15863 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015864 //VHT20 is supporting 0~8
15865 if (rate_flags & eHAL_TX_RATE_VHT20)
15866 maxMCSIdx = 8;
15867 else
15868 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070015869 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015870
c_hpothu79aab322014-07-14 21:11:01 +053015871 if (0 != rssidx)/*check for scaled */
15872 {
15873 //get middle rate MCS index if rssi=1/2
15874 for (i=0; i <= maxMCSIdx; i++)
15875 {
15876 if (sinfo->signal <= rssiMcsTbl[mode][i])
15877 {
15878 maxMCSIdx = i;
15879 break;
15880 }
15881 }
15882 }
15883
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015884 if (rate_flags & eHAL_TX_RATE_VHT80)
15885 {
15886 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
15887 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
15888 }
15889 else if (rate_flags & eHAL_TX_RATE_VHT40)
15890 {
15891 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
15892 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
15893 }
15894 else if (rate_flags & eHAL_TX_RATE_VHT20)
15895 {
15896 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
15897 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
15898 }
15899
Leo Chang6f8870f2013-03-26 18:11:36 -070015900 maxSpeedMCS = 1;
15901 if (currentRate > maxRate)
15902 {
15903 maxRate = currentRate;
15904 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015905
Leo Chang6f8870f2013-03-26 18:11:36 -070015906 }
15907 else
15908#endif /* WLAN_FEATURE_11AC */
15909 {
15910 if (rate_flags & eHAL_TX_RATE_HT40)
15911 {
15912 rateFlag |= 1;
15913 }
15914 if (rate_flags & eHAL_TX_RATE_SGI)
15915 {
15916 rateFlag |= 2;
15917 }
15918
Girish Gowli01abcee2014-07-31 20:18:55 +053015919 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053015920 if (rssidx == 1 || rssidx == 2)
15921 {
15922 //get middle rate MCS index if rssi=1/2
15923 for (i=0; i <= 7; i++)
15924 {
15925 if (sinfo->signal <= rssiMcsTbl[mode][i])
15926 {
15927 temp = i+1;
15928 break;
15929 }
15930 }
15931 }
c_hpothu79aab322014-07-14 21:11:01 +053015932
15933 for (i = 0; i < MCSLeng; i++)
15934 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015935 for (j = 0; j < temp; j++)
15936 {
15937 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
15938 {
15939 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015940 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015941 break;
15942 }
15943 }
15944 if ((j < temp) && (currentRate > maxRate))
15945 {
15946 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070015947 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015948 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015949 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015950 }
15951 }
15952
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015953 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
15954 {
15955 maxRate = myRate;
15956 maxSpeedMCS = 1;
15957 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15958 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015959 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053015960 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070015961 {
15962 maxRate = myRate;
15963 if (rate_flags & eHAL_TX_RATE_LEGACY)
15964 {
15965 maxSpeedMCS = 0;
15966 }
15967 else
15968 {
15969 maxSpeedMCS = 1;
15970 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15971 }
15972 }
15973
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015974 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070015975 {
15976 sinfo->txrate.legacy = maxRate;
15977#ifdef LINKSPEED_DEBUG_ENABLED
15978 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
15979#endif //LINKSPEED_DEBUG_ENABLED
15980 }
15981 else
15982 {
15983 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070015984#ifdef WLAN_FEATURE_11AC
15985 sinfo->txrate.nss = 1;
15986 if (rate_flags & eHAL_TX_RATE_VHT80)
15987 {
15988 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015989 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070015990 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015991 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070015992 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015993 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15994 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15995 }
15996 else if (rate_flags & eHAL_TX_RATE_VHT20)
15997 {
15998 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15999 }
16000#endif /* WLAN_FEATURE_11AC */
16001 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
16002 {
16003 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16004 if (rate_flags & eHAL_TX_RATE_HT40)
16005 {
16006 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16007 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016008 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016009 if (rate_flags & eHAL_TX_RATE_SGI)
16010 {
16011 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16012 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016013
Jeff Johnson295189b2012-06-20 16:38:30 -070016014#ifdef LINKSPEED_DEBUG_ENABLED
16015 pr_info("Reporting MCS rate %d flags %x\n",
16016 sinfo->txrate.mcs,
16017 sinfo->txrate.flags );
16018#endif //LINKSPEED_DEBUG_ENABLED
16019 }
16020 }
16021 else
16022 {
16023 // report current rate instead of max rate
16024
16025 if (rate_flags & eHAL_TX_RATE_LEGACY)
16026 {
16027 //provide to the UI in units of 100kbps
16028 sinfo->txrate.legacy = myRate;
16029#ifdef LINKSPEED_DEBUG_ENABLED
16030 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
16031#endif //LINKSPEED_DEBUG_ENABLED
16032 }
16033 else
16034 {
16035 //must be MCS
16036 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016037#ifdef WLAN_FEATURE_11AC
16038 sinfo->txrate.nss = 1;
16039 if (rate_flags & eHAL_TX_RATE_VHT80)
16040 {
16041 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16042 }
16043 else
16044#endif /* WLAN_FEATURE_11AC */
16045 {
16046 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16047 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016048 if (rate_flags & eHAL_TX_RATE_SGI)
16049 {
16050 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16051 }
16052 if (rate_flags & eHAL_TX_RATE_HT40)
16053 {
16054 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16055 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016056#ifdef WLAN_FEATURE_11AC
16057 else if (rate_flags & eHAL_TX_RATE_VHT80)
16058 {
16059 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
16060 }
16061#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070016062#ifdef LINKSPEED_DEBUG_ENABLED
16063 pr_info("Reporting actual MCS rate %d flags %x\n",
16064 sinfo->txrate.mcs,
16065 sinfo->txrate.flags );
16066#endif //LINKSPEED_DEBUG_ENABLED
16067 }
16068 }
16069 sinfo->filled |= STATION_INFO_TX_BITRATE;
16070
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016071 sinfo->tx_packets =
16072 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
16073 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
16074 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
16075 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
16076
16077 sinfo->tx_retries =
16078 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
16079 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
16080 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
16081 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
16082
16083 sinfo->tx_failed =
16084 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
16085 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
16086 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
16087 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
16088
16089 sinfo->filled |=
16090 STATION_INFO_TX_PACKETS |
16091 STATION_INFO_TX_RETRIES |
16092 STATION_INFO_TX_FAILED;
16093
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053016094 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
16095 sinfo->filled |= STATION_INFO_RX_PACKETS;
16096
16097 if (rate_flags & eHAL_TX_RATE_LEGACY)
16098 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
16099 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
16100 sinfo->rx_packets);
16101 else
16102 hddLog(LOG1,
16103 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
16104 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
16105 sinfo->tx_packets, sinfo->rx_packets);
16106
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016107 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16108 TRACE_CODE_HDD_CFG80211_GET_STA,
16109 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016110 EXIT();
16111 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016112}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016113#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16114static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16115 const u8* mac, struct station_info *sinfo)
16116#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016117static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16118 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016119#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016120{
16121 int ret;
16122
16123 vos_ssr_protect(__func__);
16124 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
16125 vos_ssr_unprotect(__func__);
16126
16127 return ret;
16128}
16129
16130static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070016131 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070016132{
16133 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016134 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016135 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016136 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016137
Jeff Johnsone7245742012-09-05 17:12:55 -070016138 ENTER();
16139
Jeff Johnson295189b2012-06-20 16:38:30 -070016140 if (NULL == pAdapter)
16141 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016142 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016143 return -ENODEV;
16144 }
16145
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016146 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16147 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
16148 pAdapter->sessionId, timeout));
16149
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016150 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016151 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016152 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016153 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016154 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016155 }
16156
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016157 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
16158 (TRUE == pHddCtx->hdd_wlan_suspended) &&
16159 (pHddCtx->cfg_ini->fhostArpOffload) &&
16160 (eConnectionState_Associated ==
16161 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
16162 {
Amar Singhald53568e2013-09-26 11:03:45 -070016163
16164 hddLog(VOS_TRACE_LEVEL_INFO,
16165 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053016166 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016167 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16168 {
16169 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016170 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016171 __func__, vos_status);
16172 }
16173 }
16174
Jeff Johnson295189b2012-06-20 16:38:30 -070016175 /**The get power cmd from the supplicant gets updated by the nl only
16176 *on successful execution of the function call
16177 *we are oppositely mapped w.r.t mode in the driver
16178 **/
16179 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
16180
16181 if (VOS_STATUS_E_FAILURE == vos_status)
16182 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16184 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016185 return -EINVAL;
16186 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016187 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016188 return 0;
16189}
16190
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016191static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
16192 struct net_device *dev, bool mode, int timeout)
16193{
16194 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016195
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016196 vos_ssr_protect(__func__);
16197 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
16198 vos_ssr_unprotect(__func__);
16199
16200 return ret;
16201}
Sushant Kaushik084f6592015-09-10 13:11:56 +053016202
Jeff Johnson295189b2012-06-20 16:38:30 -070016203#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016204static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
16205 struct net_device *netdev,
16206 u8 key_index)
16207{
16208 ENTER();
16209 return 0;
16210}
16211
Jeff Johnson295189b2012-06-20 16:38:30 -070016212static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016213 struct net_device *netdev,
16214 u8 key_index)
16215{
16216 int ret;
16217 vos_ssr_protect(__func__);
16218 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
16219 vos_ssr_unprotect(__func__);
16220 return ret;
16221}
16222#endif //LINUX_VERSION_CODE
16223
16224#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16225static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16226 struct net_device *dev,
16227 struct ieee80211_txq_params *params)
16228{
16229 ENTER();
16230 return 0;
16231}
16232#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16233static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16234 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016235{
Jeff Johnsone7245742012-09-05 17:12:55 -070016236 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070016237 return 0;
16238}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016239#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070016240
16241#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16242static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016243 struct net_device *dev,
16244 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016245{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016246 int ret;
16247
16248 vos_ssr_protect(__func__);
16249 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
16250 vos_ssr_unprotect(__func__);
16251 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016252}
16253#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16254static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
16255 struct ieee80211_txq_params *params)
16256{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016257 int ret;
16258
16259 vos_ssr_protect(__func__);
16260 ret = __wlan_hdd_set_txq_params(wiphy, params);
16261 vos_ssr_unprotect(__func__);
16262 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016263}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016264#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016265
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016266static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016267 struct net_device *dev,
16268 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070016269{
16270 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016271 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016272 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016273 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016274 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016275 v_CONTEXT_t pVosContext = NULL;
16276 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016277
Jeff Johnsone7245742012-09-05 17:12:55 -070016278 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016279
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016280 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016281 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016282 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016283 return -EINVAL;
16284 }
16285
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016286 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16287 TRACE_CODE_HDD_CFG80211_DEL_STA,
16288 pAdapter->sessionId, pAdapter->device_mode));
16289
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016290 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16291 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016292 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016293 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016294 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016295 }
16296
Jeff Johnson295189b2012-06-20 16:38:30 -070016297 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016298 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016299 )
16300 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016301 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16302 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16303 if(pSapCtx == NULL){
16304 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16305 FL("psapCtx is NULL"));
16306 return -ENOENT;
16307 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016308 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016309 {
16310 v_U16_t i;
16311 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16312 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016313 if ((pSapCtx->aStaInfo[i].isUsed) &&
16314 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016315 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016316 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016317 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016318 ETHER_ADDR_LEN);
16319
Jeff Johnson295189b2012-06-20 16:38:30 -070016320 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016321 "%s: Delete STA with MAC::"
16322 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016323 __func__,
16324 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16325 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016326 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016327 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016328 }
16329 }
16330 }
16331 else
16332 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016333
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016334 vos_status = hdd_softap_GetStaId(pAdapter,
16335 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016336 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16337 {
16338 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016339 "%s: Skip this DEL STA as this is not used::"
16340 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016341 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016342 return -ENOENT;
16343 }
16344
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016345 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016346 {
16347 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016348 "%s: Skip this DEL STA as deauth is in progress::"
16349 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016350 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016351 return -ENOENT;
16352 }
16353
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016354 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016355
Jeff Johnson295189b2012-06-20 16:38:30 -070016356 hddLog(VOS_TRACE_LEVEL_INFO,
16357 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016358 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016359 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016360 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016361
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016362 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016363 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16364 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016365 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016366 hddLog(VOS_TRACE_LEVEL_INFO,
16367 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016368 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016369 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016370 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016371 return -ENOENT;
16372 }
16373
Jeff Johnson295189b2012-06-20 16:38:30 -070016374 }
16375 }
16376
16377 EXIT();
16378
16379 return 0;
16380}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016381
16382#ifdef CFG80211_DEL_STA_V2
16383static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16384 struct net_device *dev,
16385 struct station_del_parameters *param)
16386#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016387#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16388static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16389 struct net_device *dev, const u8 *mac)
16390#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016391static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16392 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016393#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016394#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016395{
16396 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016397 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016398
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016399 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016400
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016401#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016402 if (NULL == param) {
16403 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016404 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016405 return -EINVAL;
16406 }
16407
16408 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16409 param->subtype, &delStaParams);
16410
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016411#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016412 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016413 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016414#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016415 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16416
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016417 vos_ssr_unprotect(__func__);
16418
16419 return ret;
16420}
16421
16422static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016423 struct net_device *dev,
16424#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16425 const u8 *mac,
16426#else
16427 u8 *mac,
16428#endif
16429 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016430{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016431 hdd_adapter_t *pAdapter;
16432 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016433 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016434#ifdef FEATURE_WLAN_TDLS
16435 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016436
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016437 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016438
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016439 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16440 if (NULL == pAdapter)
16441 {
16442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16443 "%s: Adapter is NULL",__func__);
16444 return -EINVAL;
16445 }
16446 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16447 status = wlan_hdd_validate_context(pHddCtx);
16448 if (0 != status)
16449 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016450 return status;
16451 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016452
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016453 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16454 TRACE_CODE_HDD_CFG80211_ADD_STA,
16455 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016456 mask = params->sta_flags_mask;
16457
16458 set = params->sta_flags_set;
16459
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016461 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16462 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016463
16464 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16465 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016466 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016467 }
16468 }
16469#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016470 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016471 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016472}
16473
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016474#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16475static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16476 struct net_device *dev, const u8 *mac,
16477 struct station_parameters *params)
16478#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016479static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16480 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016481#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016482{
16483 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016484
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016485 vos_ssr_protect(__func__);
16486 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16487 vos_ssr_unprotect(__func__);
16488
16489 return ret;
16490}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016491#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016492
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016493static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016494 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016495{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016496 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16497 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016498 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016499 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016500 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016501 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016502
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016503 ENTER();
16504
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016505 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016506 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016507 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016508 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016509 return -EINVAL;
16510 }
16511
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016512 if (!pmksa) {
16513 hddLog(LOGE, FL("pmksa is NULL"));
16514 return -EINVAL;
16515 }
16516
16517 if (!pmksa->bssid || !pmksa->pmkid) {
16518 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16519 pmksa->bssid, pmksa->pmkid);
16520 return -EINVAL;
16521 }
16522
16523 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16524 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16525
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016526 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16527 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016528 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016529 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016530 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016531 }
16532
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016533 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016534 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16535
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016536 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16537 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016538
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016539 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016540 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016541 &pmk_id, 1, FALSE);
16542
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016543 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16544 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16545 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016546
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016547 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016548 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016549}
16550
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016551static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16552 struct cfg80211_pmksa *pmksa)
16553{
16554 int ret;
16555
16556 vos_ssr_protect(__func__);
16557 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16558 vos_ssr_unprotect(__func__);
16559
16560 return ret;
16561}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016562
Wilson Yang6507c4e2013-10-01 20:11:19 -070016563
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016564static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016565 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016566{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016567 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16568 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016569 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016570 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016571
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016572 ENTER();
16573
Wilson Yang6507c4e2013-10-01 20:11:19 -070016574 /* Validate pAdapter */
16575 if (NULL == pAdapter)
16576 {
16577 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16578 return -EINVAL;
16579 }
16580
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016581 if (!pmksa) {
16582 hddLog(LOGE, FL("pmksa is NULL"));
16583 return -EINVAL;
16584 }
16585
16586 if (!pmksa->bssid) {
16587 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16588 return -EINVAL;
16589 }
16590
Kiet Lam98c46a12014-10-31 15:34:57 -070016591 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16592 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16593
Wilson Yang6507c4e2013-10-01 20:11:19 -070016594 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16595 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016596 if (0 != status)
16597 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016598 return status;
16599 }
16600
16601 /*Retrieve halHandle*/
16602 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16603
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016604 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16605 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16606 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016607 /* Delete the PMKID CSR cache */
16608 if (eHAL_STATUS_SUCCESS !=
16609 sme_RoamDelPMKIDfromCache(halHandle,
16610 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16611 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16612 MAC_ADDR_ARRAY(pmksa->bssid));
16613 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016614 }
16615
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016616 EXIT();
16617 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016618}
16619
Wilson Yang6507c4e2013-10-01 20:11:19 -070016620
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016621static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16622 struct cfg80211_pmksa *pmksa)
16623{
16624 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016625
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016626 vos_ssr_protect(__func__);
16627 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16628 vos_ssr_unprotect(__func__);
16629
16630 return ret;
16631
16632}
16633
16634static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016635{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016636 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16637 tHalHandle halHandle;
16638 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016639 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016640
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016641 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016642
16643 /* Validate pAdapter */
16644 if (NULL == pAdapter)
16645 {
16646 hddLog(VOS_TRACE_LEVEL_ERROR,
16647 "%s: Invalid Adapter" ,__func__);
16648 return -EINVAL;
16649 }
16650
16651 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16652 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016653 if (0 != status)
16654 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016655 return status;
16656 }
16657
16658 /*Retrieve halHandle*/
16659 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16660
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016661 /* Flush the PMKID cache in CSR */
16662 if (eHAL_STATUS_SUCCESS !=
16663 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
16664 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
16665 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016666 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016667 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080016668 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016669}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016670
16671static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
16672{
16673 int ret;
16674
16675 vos_ssr_protect(__func__);
16676 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
16677 vos_ssr_unprotect(__func__);
16678
16679 return ret;
16680}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016681#endif
16682
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016683#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016684static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16685 struct net_device *dev,
16686 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016687{
16688 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16689 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016690 hdd_context_t *pHddCtx;
16691 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016692
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016693 ENTER();
16694
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016695 if (NULL == pAdapter)
16696 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016697 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016698 return -ENODEV;
16699 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016700 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16701 ret = wlan_hdd_validate_context(pHddCtx);
16702 if (0 != ret)
16703 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016704 return ret;
16705 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016706 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016707 if (NULL == pHddStaCtx)
16708 {
16709 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
16710 return -EINVAL;
16711 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016712
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016713 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16714 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
16715 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016716 // Added for debug on reception of Re-assoc Req.
16717 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
16718 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016719 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016720 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080016721 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016722 }
16723
16724#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080016725 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016726 ftie->ie_len);
16727#endif
16728
16729 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016730 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
16731 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016732 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016733
16734 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016735 return 0;
16736}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016737
16738static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16739 struct net_device *dev,
16740 struct cfg80211_update_ft_ies_params *ftie)
16741{
16742 int ret;
16743
16744 vos_ssr_protect(__func__);
16745 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
16746 vos_ssr_unprotect(__func__);
16747
16748 return ret;
16749}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016750#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016751
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016752#ifdef FEATURE_WLAN_SCAN_PNO
16753
16754void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
16755 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
16756{
16757 int ret;
16758 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
16759 hdd_context_t *pHddCtx;
16760
Nirav Shah80830bf2013-12-31 16:35:12 +053016761 ENTER();
16762
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016763 if (NULL == pAdapter)
16764 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016766 "%s: HDD adapter is Null", __func__);
16767 return ;
16768 }
16769
16770 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16771 if (NULL == pHddCtx)
16772 {
16773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16774 "%s: HDD context is Null!!!", __func__);
16775 return ;
16776 }
16777
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016778 spin_lock(&pHddCtx->schedScan_lock);
16779 if (TRUE == pHddCtx->isWiphySuspended)
16780 {
16781 pHddCtx->isSchedScanUpdatePending = TRUE;
16782 spin_unlock(&pHddCtx->schedScan_lock);
16783 hddLog(VOS_TRACE_LEVEL_INFO,
16784 "%s: Update cfg80211 scan database after it resume", __func__);
16785 return ;
16786 }
16787 spin_unlock(&pHddCtx->schedScan_lock);
16788
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016789 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
16790
16791 if (0 > ret)
16792 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053016793 else
16794 {
16795 /* Acquire wakelock to handle the case where APP's tries to suspend
16796 * immediatly after the driver gets connect request(i.e after pno)
16797 * from supplicant, this result in app's is suspending and not able
16798 * to process the connect request to AP */
16799 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
16800 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016801 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16803 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016804}
16805
16806/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016807 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016808 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016809 */
16810static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
16811{
16812 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16813 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016814 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016815 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16816 int status = 0;
16817 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
16818
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016819 /* The current firmware design does not allow PNO during any
16820 * active sessions. Hence, determine the active sessions
16821 * and return a failure.
16822 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016823 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
16824 {
16825 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016826 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016827
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016828 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
16829 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
16830 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
16831 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
16832 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053016833 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016834 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016835 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016836 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016837 }
16838 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16839 pAdapterNode = pNext;
16840 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016841 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016842}
16843
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016844void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
16845{
16846 hdd_adapter_t *pAdapter = callbackContext;
16847 hdd_context_t *pHddCtx;
16848
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016849 ENTER();
16850
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016851 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
16852 {
16853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16854 FL("Invalid adapter or adapter has invalid magic"));
16855 return;
16856 }
16857
16858 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16859 if (0 != wlan_hdd_validate_context(pHddCtx))
16860 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016861 return;
16862 }
16863
c_hpothub53c45d2014-08-18 16:53:14 +053016864 if (VOS_STATUS_SUCCESS != status)
16865 {
16866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016867 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053016868 pHddCtx->isPnoEnable = FALSE;
16869 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016870
16871 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
16872 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016873 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016874}
16875
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016876/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016877 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
16878 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016879 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016880static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016881 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16882{
16883 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016884 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016885 hdd_context_t *pHddCtx;
16886 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016887 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053016888 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
16889 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016890 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16891 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016892 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016893 hdd_config_t *pConfig = NULL;
16894 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016895
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016896 ENTER();
16897
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016898 if (NULL == pAdapter)
16899 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016901 "%s: HDD adapter is Null", __func__);
16902 return -ENODEV;
16903 }
16904
16905 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016906 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016907
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016908 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016909 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016910 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016911 }
16912
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016913 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016914 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16915 if (NULL == hHal)
16916 {
16917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16918 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016919 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016920 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016921 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16922 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
16923 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053016924 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016925 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053016926 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016927 {
16928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16929 "%s: aborting the existing scan is unsuccessfull", __func__);
16930 return -EBUSY;
16931 }
16932
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016933 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016934 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016936 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016937 return -EBUSY;
16938 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016939
c_hpothu37f21312014-04-09 21:49:54 +053016940 if (TRUE == pHddCtx->isPnoEnable)
16941 {
16942 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16943 FL("already PNO is enabled"));
16944 return -EBUSY;
16945 }
c_hpothu225aa7c2014-10-22 17:45:13 +053016946
16947 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
16948 {
16949 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16950 "%s: abort ROC failed ", __func__);
16951 return -EBUSY;
16952 }
16953
c_hpothu37f21312014-04-09 21:49:54 +053016954 pHddCtx->isPnoEnable = TRUE;
16955
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016956 pnoRequest.enable = 1; /*Enable PNO */
16957 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016958
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016959 if (( !pnoRequest.ucNetworksCount ) ||
16960 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016961 {
16962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016963 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016964 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016965 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016966 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016967 goto error;
16968 }
16969
16970 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
16971 {
16972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016973 "%s: Incorrect number of channels %d",
16974 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016975 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016976 goto error;
16977 }
16978
16979 /* Framework provides one set of channels(all)
16980 * common for all saved profile */
16981 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16982 channels_allowed, &num_channels_allowed))
16983 {
16984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16985 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016986 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016987 goto error;
16988 }
16989 /* Checking each channel against allowed channel list */
16990 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053016991 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016992 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016993 char chList [(request->n_channels*5)+1];
16994 int len;
16995 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016996 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016997 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016998 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016999 if (request->channels[i]->hw_value == channels_allowed[indx])
17000 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017001 if ((!pConfig->enableDFSPnoChnlScan) &&
17002 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
17003 {
17004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17005 "%s : Dropping DFS channel : %d",
17006 __func__,channels_allowed[indx]);
17007 num_ignore_dfs_ch++;
17008 break;
17009 }
17010
Nirav Shah80830bf2013-12-31 16:35:12 +053017011 valid_ch[num_ch++] = request->channels[i]->hw_value;
17012 len += snprintf(chList+len, 5, "%d ",
17013 request->channels[i]->hw_value);
17014 break ;
17015 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017016 }
17017 }
Nirav Shah80830bf2013-12-31 16:35:12 +053017018 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017019
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017020 /*If all channels are DFS and dropped, then ignore the PNO request*/
17021 if (num_ignore_dfs_ch == request->n_channels)
17022 {
17023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17024 "%s : All requested channels are DFS channels", __func__);
17025 ret = -EINVAL;
17026 goto error;
17027 }
17028 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017029
17030 pnoRequest.aNetworks =
17031 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17032 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017033 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017034 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17035 FL("failed to allocate memory aNetworks %u"),
17036 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17037 goto error;
17038 }
17039 vos_mem_zero(pnoRequest.aNetworks,
17040 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17041
17042 /* Filling per profile params */
17043 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
17044 {
17045 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017046 request->match_sets[i].ssid.ssid_len;
17047
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017048 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
17049 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017050 {
17051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017052 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017053 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017054 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017055 goto error;
17056 }
17057
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017058 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017059 request->match_sets[i].ssid.ssid,
17060 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17062 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017063 i, pnoRequest.aNetworks[i].ssId.ssId);
17064 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
17065 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
17066 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017067
17068 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017069 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
17070 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017071
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017072 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017073 }
17074
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017075 for (i = 0; i < request->n_ssids; i++)
17076 {
17077 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017078 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017079 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017080 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017081 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017082 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017083 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017084 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017085 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017086 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017087 break;
17088 }
17089 j++;
17090 }
17091 }
17092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17093 "Number of hidden networks being Configured = %d",
17094 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080017096 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017097
17098 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17099 if (pnoRequest.p24GProbeTemplate == NULL)
17100 {
17101 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17102 FL("failed to allocate memory p24GProbeTemplate %u"),
17103 SIR_PNO_MAX_PB_REQ_SIZE);
17104 goto error;
17105 }
17106
17107 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17108 if (pnoRequest.p5GProbeTemplate == NULL)
17109 {
17110 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17111 FL("failed to allocate memory p5GProbeTemplate %u"),
17112 SIR_PNO_MAX_PB_REQ_SIZE);
17113 goto error;
17114 }
17115
17116 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17117 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17118
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053017119 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
17120 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017121 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017122 pnoRequest.us24GProbeTemplateLen = request->ie_len;
17123 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
17124 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017125
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017126 pnoRequest.us5GProbeTemplateLen = request->ie_len;
17127 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
17128 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017129 }
17130
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017131 /* Driver gets only one time interval which is hardcoded in
17132 * supplicant for 10000ms. Taking power consumption into account 6 timers
17133 * will be used, Timervalue is increased exponentially i.e 10,20,40,
17134 * 80,160,320 secs. And number of scan cycle for each timer
17135 * is configurable through INI param gPNOScanTimerRepeatValue.
17136 * If it is set to 0 only one timer will be used and PNO scan cycle
17137 * will be repeated after each interval specified by supplicant
17138 * till PNO is disabled.
17139 */
17140 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017141 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017142 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017143 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017144 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
17145
17146 tempInterval = (request->interval)/1000;
17147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17148 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
17149 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017150 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017151 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017152 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017153 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017154 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017155 tempInterval *= 2;
17156 }
17157 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017158 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017159
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017160 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017161
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017162 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017163 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17164 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017165 pAdapter->pno_req_status = 0;
17166
Nirav Shah80830bf2013-12-31 16:35:12 +053017167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17168 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017169 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
17170 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053017171
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017172 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017173 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017174 hdd_cfg80211_sched_scan_done_callback, pAdapter);
17175 if (eHAL_STATUS_SUCCESS != status)
17176 {
17177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017178 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017179 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017180 goto error;
17181 }
17182
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017183 ret = wait_for_completion_timeout(
17184 &pAdapter->pno_comp_var,
17185 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17186 if (0 >= ret)
17187 {
17188 // Did not receive the response for PNO enable in time.
17189 // Assuming the PNO enable was success.
17190 // Returning error from here, because we timeout, results
17191 // in side effect of Wifi (Wifi Setting) not to work.
17192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17193 FL("Timed out waiting for PNO to be Enabled"));
17194 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017195 }
17196
17197 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053017198 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017199
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017200error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17202 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053017203 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017204 if (pnoRequest.aNetworks)
17205 vos_mem_free(pnoRequest.aNetworks);
17206 if (pnoRequest.p24GProbeTemplate)
17207 vos_mem_free(pnoRequest.p24GProbeTemplate);
17208 if (pnoRequest.p5GProbeTemplate)
17209 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017210
17211 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017212 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017213}
17214
17215/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017216 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
17217 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017218 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017219static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
17220 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17221{
17222 int ret;
17223
17224 vos_ssr_protect(__func__);
17225 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
17226 vos_ssr_unprotect(__func__);
17227
17228 return ret;
17229}
17230
17231/*
17232 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
17233 * Function to disable PNO
17234 */
17235static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017236 struct net_device *dev)
17237{
17238 eHalStatus status = eHAL_STATUS_FAILURE;
17239 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17240 hdd_context_t *pHddCtx;
17241 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017242 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017243 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017244
17245 ENTER();
17246
17247 if (NULL == pAdapter)
17248 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017250 "%s: HDD adapter is Null", __func__);
17251 return -ENODEV;
17252 }
17253
17254 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017255
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017256 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017257 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017259 "%s: HDD context is Null", __func__);
17260 return -ENODEV;
17261 }
17262
17263 /* The return 0 is intentional when isLogpInProgress and
17264 * isLoadUnloadInProgress. We did observe a crash due to a return of
17265 * failure in sched_scan_stop , especially for a case where the unload
17266 * of the happens at the same time. The function __cfg80211_stop_sched_scan
17267 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
17268 * success. If it returns a failure , then its next invocation due to the
17269 * clean up of the second interface will have the dev pointer corresponding
17270 * to the first one leading to a crash.
17271 */
17272 if (pHddCtx->isLogpInProgress)
17273 {
17274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17275 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017276 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017277 return ret;
17278 }
17279
Mihir Shete18156292014-03-11 15:38:30 +053017280 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017281 {
17282 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17283 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17284 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017285 }
17286
17287 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17288 if (NULL == hHal)
17289 {
17290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17291 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017292 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017293 }
17294
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017295 pnoRequest.enable = 0; /* Disable PNO */
17296 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017297
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017298 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17299 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17300 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017301
17302 INIT_COMPLETION(pAdapter->pno_comp_var);
17303 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17304 pnoRequest.callbackContext = pAdapter;
17305 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017306 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017307 pAdapter->sessionId,
17308 NULL, pAdapter);
17309 if (eHAL_STATUS_SUCCESS != status)
17310 {
17311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17312 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017313 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017314 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017315 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017316 ret = wait_for_completion_timeout(
17317 &pAdapter->pno_comp_var,
17318 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17319 if (0 >= ret)
17320 {
17321 // Did not receive the response for PNO disable in time.
17322 // Assuming the PNO disable was success.
17323 // Returning error from here, because we timeout, results
17324 // in side effect of Wifi (Wifi Setting) not to work.
17325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17326 FL("Timed out waiting for PNO to be disabled"));
17327 ret = 0;
17328 }
17329
17330 ret = pAdapter->pno_req_status;
17331 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017332
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017333error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017335 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017336
17337 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017338 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017339}
17340
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017341/*
17342 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17343 * NL interface to disable PNO
17344 */
17345static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17346 struct net_device *dev)
17347{
17348 int ret;
17349
17350 vos_ssr_protect(__func__);
17351 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17352 vos_ssr_unprotect(__func__);
17353
17354 return ret;
17355}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017356#endif /*FEATURE_WLAN_SCAN_PNO*/
17357
17358
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017359#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017360#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017361static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17362 struct net_device *dev,
17363 u8 *peer, u8 action_code,
17364 u8 dialog_token,
17365 u16 status_code, u32 peer_capability,
17366 const u8 *buf, size_t len)
17367#else /* TDLS_MGMT_VERSION2 */
17368#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17369static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17370 struct net_device *dev,
17371 const u8 *peer, u8 action_code,
17372 u8 dialog_token, u16 status_code,
17373 u32 peer_capability, bool initiator,
17374 const u8 *buf, size_t len)
17375#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17376static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17377 struct net_device *dev,
17378 const u8 *peer, u8 action_code,
17379 u8 dialog_token, u16 status_code,
17380 u32 peer_capability, const u8 *buf,
17381 size_t len)
17382#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17383static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17384 struct net_device *dev,
17385 u8 *peer, u8 action_code,
17386 u8 dialog_token,
17387 u16 status_code, u32 peer_capability,
17388 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017389#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017390static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17391 struct net_device *dev,
17392 u8 *peer, u8 action_code,
17393 u8 dialog_token,
17394 u16 status_code, const u8 *buf,
17395 size_t len)
17396#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017397#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017398{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017399 hdd_adapter_t *pAdapter;
17400 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017401 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017402 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017403 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017404 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017405 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017406 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017407#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017408 u32 peer_capability = 0;
17409#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017410 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017411 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017412
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017413 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17414 if (NULL == pAdapter)
17415 {
17416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17417 "%s: Adapter is NULL",__func__);
17418 return -EINVAL;
17419 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017420 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17421 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17422 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017423
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017424 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017425 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017426 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017428 "Invalid arguments");
17429 return -EINVAL;
17430 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017431
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017432 if (pHddCtx->isLogpInProgress)
17433 {
17434 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17435 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017436 wlan_hdd_tdls_set_link_status(pAdapter,
17437 peer,
17438 eTDLS_LINK_IDLE,
17439 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017440 return -EBUSY;
17441 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017442
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017443 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17444 {
17445 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17446 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17447 return -EAGAIN;
17448 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017449
Hoonki Lee27511902013-03-14 18:19:06 -070017450 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017451 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017452 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017453 "%s: TDLS mode is disabled OR not enabled in FW."
17454 MAC_ADDRESS_STR " action %d declined.",
17455 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017456 return -ENOTSUPP;
17457 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017458
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017459 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17460
17461 if( NULL == pHddStaCtx )
17462 {
17463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17464 "%s: HDD station context NULL ",__func__);
17465 return -EINVAL;
17466 }
17467
17468 /* STA should be connected and authenticated
17469 * before sending any TDLS frames
17470 */
17471 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17472 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17473 {
17474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17475 "STA is not connected or unauthenticated. "
17476 "connState %u, uIsAuthenticated %u",
17477 pHddStaCtx->conn_info.connState,
17478 pHddStaCtx->conn_info.uIsAuthenticated);
17479 return -EAGAIN;
17480 }
17481
Hoonki Lee27511902013-03-14 18:19:06 -070017482 /* other than teardown frame, other mgmt frames are not sent if disabled */
17483 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17484 {
17485 /* if tdls_mode is disabled to respond to peer's request */
17486 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17487 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017489 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017490 " TDLS mode is disabled. action %d declined.",
17491 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017492
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017493 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017494 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017495
17496 if (vos_max_concurrent_connections_reached())
17497 {
17498 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17499 return -EINVAL;
17500 }
Hoonki Lee27511902013-03-14 18:19:06 -070017501 }
17502
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017503 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17504 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017505 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017506 {
17507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017508 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017509 " TDLS setup is ongoing. action %d declined.",
17510 __func__, MAC_ADDR_ARRAY(peer), action_code);
17511 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017512 }
17513 }
17514
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017515 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17516 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017517 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017518 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17519 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017520 {
17521 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17522 we return error code at 'add_station()'. Hence we have this
17523 check again in addtion to add_station().
17524 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017525 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017526 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17528 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017529 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
17530 __func__, MAC_ADDR_ARRAY(peer), action_code,
17531 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053017532 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080017533 }
17534 else
17535 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017536 /* maximum reached. tweak to send error code to peer and return
17537 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017538 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17540 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017541 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
17542 __func__, MAC_ADDR_ARRAY(peer), status_code,
17543 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070017544 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017545 /* fall through to send setup resp with failure status
17546 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017547 }
17548 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017549 else
17550 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017551 mutex_lock(&pHddCtx->tdls_lock);
17552 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017553 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017554 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017555 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017557 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17558 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017559 return -EPERM;
17560 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017561 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017562 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017563 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017564
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017566 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017567 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17568 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017569
Hoonki Leea34dd892013-02-05 22:56:02 -080017570 /*Except teardown responder will not be used so just make 0*/
17571 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017572 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017573 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017574
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017575 mutex_lock(&pHddCtx->tdls_lock);
17576 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017577
17578 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17579 responder = pTdlsPeer->is_responder;
17580 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017581 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017583 "%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 -070017584 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17585 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017586 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017587 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017588 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017589 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017590 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017591
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017592 /* Discard TDLS setup if peer is removed by user app */
17593 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
17594 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17595 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
17596 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
17597
17598 mutex_lock(&pHddCtx->tdls_lock);
17599 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17600 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
17601 mutex_unlock(&pHddCtx->tdls_lock);
17602 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
17603 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
17604 MAC_ADDR_ARRAY(peer), action_code);
17605 return -EINVAL;
17606 }
17607 mutex_unlock(&pHddCtx->tdls_lock);
17608 }
17609
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017610 /* For explicit trigger of DIS_REQ come out of BMPS for
17611 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017612 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053017613 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017614 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17615 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070017616 {
17617 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
17618 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017620 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017621 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
17622 if (status != VOS_STATUS_SUCCESS) {
17623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
17624 }
Hoonki Lee14621352013-04-16 17:51:19 -070017625 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017626 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017627 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
17629 }
17630 }
Hoonki Lee14621352013-04-16 17:51:19 -070017631 }
17632
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017633 /* make sure doesn't call send_mgmt() while it is pending */
17634 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
17635 {
17636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017637 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017638 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017639 ret = -EBUSY;
17640 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017641 }
17642
17643 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017644 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
17645
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017646 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
17647 pAdapter->sessionId, peer, action_code, dialog_token,
17648 status_code, peer_capability, (tANI_U8 *)buf, len,
17649 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017650
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017651 if (VOS_STATUS_SUCCESS != status)
17652 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17654 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017655 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017656 ret = -EINVAL;
17657 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017658 }
17659
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17661 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
17662 WAIT_TIME_TDLS_MGMT);
17663
Hoonki Leed37cbb32013-04-20 00:31:14 -070017664 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
17665 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
17666
17667 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017668 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070017669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070017670 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070017671 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017672 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080017673
17674 if (pHddCtx->isLogpInProgress)
17675 {
17676 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17677 "%s: LOGP in Progress. Ignore!!!", __func__);
17678 return -EAGAIN;
17679 }
Abhishek Singh837adf22015-10-01 17:37:37 +053017680 if (rc <= 0)
17681 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
17682 WLAN_LOG_INDICATOR_HOST_DRIVER,
17683 WLAN_LOG_REASON_HDD_TIME_OUT,
17684 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080017685
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017686 ret = -EINVAL;
17687 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017688 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017689 else
17690 {
17691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17692 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
17693 __func__, rc, pAdapter->mgmtTxCompletionStatus);
17694 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017695
Gopichand Nakkala05922802013-03-14 12:23:19 -070017696 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070017697 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017698 ret = max_sta_failed;
17699 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070017700 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017701
Hoonki Leea34dd892013-02-05 22:56:02 -080017702 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
17703 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017704 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017705 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17706 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017707 }
17708 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
17709 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017710 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017711 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17712 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017713 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017714
17715 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017716
17717tx_failed:
17718 /* add_station will be called before sending TDLS_SETUP_REQ and
17719 * TDLS_SETUP_RSP and as part of add_station driver will enable
17720 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
17721 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
17722 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
17723 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
17724 */
17725
17726 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17727 (SIR_MAC_TDLS_SETUP_RSP == action_code))
17728 wlan_hdd_tdls_check_bmps(pAdapter);
17729 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017730}
17731
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017732#if TDLS_MGMT_VERSION2
17733static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17734 u8 *peer, u8 action_code, u8 dialog_token,
17735 u16 status_code, u32 peer_capability,
17736 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017737#else /* TDLS_MGMT_VERSION2 */
17738#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17739static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17740 struct net_device *dev,
17741 const u8 *peer, u8 action_code,
17742 u8 dialog_token, u16 status_code,
17743 u32 peer_capability, bool initiator,
17744 const u8 *buf, size_t len)
17745#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17746static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17747 struct net_device *dev,
17748 const u8 *peer, u8 action_code,
17749 u8 dialog_token, u16 status_code,
17750 u32 peer_capability, const u8 *buf,
17751 size_t len)
17752#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17753static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17754 struct net_device *dev,
17755 u8 *peer, u8 action_code,
17756 u8 dialog_token,
17757 u16 status_code, u32 peer_capability,
17758 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017759#else
17760static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17761 u8 *peer, u8 action_code, u8 dialog_token,
17762 u16 status_code, const u8 *buf, size_t len)
17763#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017764#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017765{
17766 int ret;
17767
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017768 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017769#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017770 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17771 dialog_token, status_code,
17772 peer_capability, buf, len);
17773#else /* TDLS_MGMT_VERSION2 */
17774#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17775 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17776 dialog_token, status_code,
17777 peer_capability, initiator,
17778 buf, len);
17779#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17780 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17781 dialog_token, status_code,
17782 peer_capability, buf, len);
17783#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17784 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17785 dialog_token, status_code,
17786 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017787#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017788 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17789 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017790#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017791#endif
17792 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017793
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017794 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017795}
Atul Mittal115287b2014-07-08 13:26:33 +053017796
17797int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017798#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17799 const u8 *peer,
17800#else
Atul Mittal115287b2014-07-08 13:26:33 +053017801 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017802#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017803 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053017804 cfg80211_exttdls_callback callback)
17805{
17806
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017807 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053017808 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017809 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053017810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17811 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
17812 __func__, MAC_ADDR_ARRAY(peer));
17813
17814 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17815 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17816
17817 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017818 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17819 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17820 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017821 return -ENOTSUPP;
17822 }
17823
17824 /* To cater the requirement of establishing the TDLS link
17825 * irrespective of the data traffic , get an entry of TDLS peer.
17826 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017827 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017828 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
17829 if (pTdlsPeer == NULL) {
17830 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17831 "%s: peer " MAC_ADDRESS_STR " not existing",
17832 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017833 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017834 return -EINVAL;
17835 }
17836
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017837 /* check FW TDLS Off Channel capability */
17838 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017839 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017840 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017841 {
17842 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
17843 pTdlsPeer->peerParams.global_operating_class =
17844 tdls_peer_params->global_operating_class;
17845 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
17846 pTdlsPeer->peerParams.min_bandwidth_kbps =
17847 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017848 /* check configured channel is valid, non dfs and
17849 * not current operating channel */
17850 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
17851 tdls_peer_params->channel)) &&
17852 (pHddStaCtx) &&
17853 (tdls_peer_params->channel !=
17854 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017855 {
17856 pTdlsPeer->isOffChannelConfigured = TRUE;
17857 }
17858 else
17859 {
17860 pTdlsPeer->isOffChannelConfigured = FALSE;
17861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17862 "%s: Configured Tdls Off Channel is not valid", __func__);
17863
17864 }
17865 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017866 "%s: tdls_off_channel %d isOffChannelConfigured %d "
17867 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017868 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017869 pTdlsPeer->isOffChannelConfigured,
17870 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017871 }
17872 else
17873 {
17874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017875 "%s: TDLS off channel FW capability %d, "
17876 "host capab %d or Invalid TDLS Peer Params", __func__,
17877 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
17878 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017879 }
17880
Atul Mittal115287b2014-07-08 13:26:33 +053017881 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
17882
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017883 mutex_unlock(&pHddCtx->tdls_lock);
17884
Atul Mittal115287b2014-07-08 13:26:33 +053017885 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17886 " %s TDLS Add Force Peer Failed",
17887 __func__);
17888 return -EINVAL;
17889 }
17890 /*EXT TDLS*/
17891
17892 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017893 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17895 " %s TDLS set callback Failed",
17896 __func__);
17897 return -EINVAL;
17898 }
17899
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017900 mutex_unlock(&pHddCtx->tdls_lock);
17901
Atul Mittal115287b2014-07-08 13:26:33 +053017902 return(0);
17903
17904}
17905
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017906int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
17907#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17908 const u8 *peer
17909#else
17910 u8 *peer
17911#endif
17912)
Atul Mittal115287b2014-07-08 13:26:33 +053017913{
17914
17915 hddTdlsPeer_t *pTdlsPeer;
17916 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053017917
Atul Mittal115287b2014-07-08 13:26:33 +053017918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17919 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
17920 __func__, MAC_ADDR_ARRAY(peer));
17921
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017922 if (0 != wlan_hdd_validate_context(pHddCtx)) {
17923 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
17924 return -EINVAL;
17925 }
17926
Atul Mittal115287b2014-07-08 13:26:33 +053017927 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17928 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17929
17930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017931 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17932 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17933 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017934 return -ENOTSUPP;
17935 }
17936
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017937 mutex_lock(&pHddCtx->tdls_lock);
17938 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053017939
17940 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017941 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017942 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017943 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053017944 __func__, MAC_ADDR_ARRAY(peer));
17945 return -EINVAL;
17946 }
17947 else {
17948 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
17949 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053017950 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
17951 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017952 /* if channel switch is configured, reset
17953 the channel for this peer */
17954 if (TRUE == pTdlsPeer->isOffChannelConfigured)
17955 {
17956 pTdlsPeer->peerParams.channel = 0;
17957 pTdlsPeer->isOffChannelConfigured = FALSE;
17958 }
Atul Mittal115287b2014-07-08 13:26:33 +053017959 }
17960
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017961 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017962 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017963 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053017964 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017965 }
Atul Mittal115287b2014-07-08 13:26:33 +053017966
17967 /*EXT TDLS*/
17968
17969 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017970 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17972 " %s TDLS set callback Failed",
17973 __func__);
17974 return -EINVAL;
17975 }
Atul Mittal115287b2014-07-08 13:26:33 +053017976
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017977 mutex_unlock(&pHddCtx->tdls_lock);
17978
17979 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053017980}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017981static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017982#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17983 const u8 *peer,
17984#else
17985 u8 *peer,
17986#endif
17987 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017988{
17989 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17990 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017991 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017992 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017993
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017994 ENTER();
17995
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017996 if (!pAdapter) {
17997 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17998 return -EINVAL;
17999 }
18000
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018001 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18002 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
18003 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018004 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018005 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070018007 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018008 return -EINVAL;
18009 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018010
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018011 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018012 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018013 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018014 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018015 }
18016
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018017
18018 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018019 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018020 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018021 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018022 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
18023 "Cannot process TDLS commands",
18024 pHddCtx->cfg_ini->fEnableTDLSSupport,
18025 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018026 return -ENOTSUPP;
18027 }
18028
18029 switch (oper) {
18030 case NL80211_TDLS_ENABLE_LINK:
18031 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018032 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018033 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053018034 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
18035 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053018036 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018037 tANI_U16 numCurrTdlsPeers = 0;
18038 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018039 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018040 tSirMacAddr peerMac;
18041 int channel;
18042 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018043
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18045 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
18046 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018047
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018048 mutex_lock(&pHddCtx->tdls_lock);
18049 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018050 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053018051 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018052 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018053 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18054 " (oper %d) not exsting. ignored",
18055 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18056 return -EINVAL;
18057 }
18058
18059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18060 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18061 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18062 "NL80211_TDLS_ENABLE_LINK");
18063
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018064 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
18065 {
18066 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
18067 MAC_ADDRESS_STR " failed",
18068 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018069 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018070 return -EINVAL;
18071 }
18072
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018073 /* before starting tdls connection, set tdls
18074 * off channel established status to default value */
18075 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018076
18077 mutex_unlock(&pHddCtx->tdls_lock);
18078
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053018079 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018080 /* TDLS Off Channel, Disable tdls channel switch,
18081 when there are more than one tdls link */
18082 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053018083 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018084 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018085 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018086 /* get connected peer and send disable tdls off chan */
18087 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018088 if ((connPeer) &&
18089 (connPeer->isOffChannelSupported == TRUE) &&
18090 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018091 {
18092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18093 "%s: More then one peer connected, Disable "
18094 "TDLS channel switch", __func__);
18095
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018096 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018097 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
18098 channel = connPeer->peerParams.channel;
18099
18100 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018101
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018102 ret = sme_SendTdlsChanSwitchReq(
18103 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018104 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018105 peerMac,
18106 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018107 TDLS_OFF_CHANNEL_BW_OFFSET,
18108 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018109 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018110 hddLog(VOS_TRACE_LEVEL_ERROR,
18111 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018112 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018113 }
18114 else
18115 {
18116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18117 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018118 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018119 "isOffChannelConfigured %d",
18120 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018121 (connPeer ? (connPeer->isOffChannelSupported)
18122 : -1),
18123 (connPeer ? (connPeer->isOffChannelConfigured)
18124 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018125 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018126 }
18127 }
18128
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018129 mutex_lock(&pHddCtx->tdls_lock);
18130 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18131 if ( NULL == pTdlsPeer ) {
18132 mutex_unlock(&pHddCtx->tdls_lock);
18133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18134 "%s: " MAC_ADDRESS_STR
18135 " (oper %d) peer got freed in other context. ignored",
18136 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18137 return -EINVAL;
18138 }
18139 peer_status = pTdlsPeer->link_status;
18140 mutex_unlock(&pHddCtx->tdls_lock);
18141
18142 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018143 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018144 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053018145
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018146 if (0 != wlan_hdd_tdls_get_link_establish_params(
18147 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018148 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018149 return -EINVAL;
18150 }
18151 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018152
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018153 ret = sme_SendTdlsLinkEstablishParams(
18154 WLAN_HDD_GET_HAL_CTX(pAdapter),
18155 pAdapter->sessionId, peer,
18156 &tdlsLinkEstablishParams);
18157 if (ret != VOS_STATUS_SUCCESS) {
18158 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
18159 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018160 /* Send TDLS peer UAPSD capabilities to the firmware and
18161 * register with the TL on after the response for this operation
18162 * is received .
18163 */
18164 ret = wait_for_completion_interruptible_timeout(
18165 &pAdapter->tdls_link_establish_req_comp,
18166 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053018167
18168 mutex_lock(&pHddCtx->tdls_lock);
18169 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18170 if ( NULL == pTdlsPeer ) {
18171 mutex_unlock(&pHddCtx->tdls_lock);
18172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18173 "%s %d: " MAC_ADDRESS_STR
18174 " (oper %d) peer got freed in other context. ignored",
18175 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
18176 (int)oper);
18177 return -EINVAL;
18178 }
18179 peer_status = pTdlsPeer->link_status;
18180 mutex_unlock(&pHddCtx->tdls_lock);
18181
18182 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018183 {
18184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018185 FL("Link Establish Request Failed Status %ld"),
18186 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018187 return -EINVAL;
18188 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018189 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018190
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018191 mutex_lock(&pHddCtx->tdls_lock);
18192 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18193 if ( NULL == pTdlsPeer ) {
18194 mutex_unlock(&pHddCtx->tdls_lock);
18195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18196 "%s: " MAC_ADDRESS_STR
18197 " (oper %d) peer got freed in other context. ignored",
18198 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18199 return -EINVAL;
18200 }
18201
Atul Mittal115287b2014-07-08 13:26:33 +053018202 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18203 eTDLS_LINK_CONNECTED,
18204 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018205 staDesc.ucSTAId = pTdlsPeer->staId;
18206 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053018207
18208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18209 "%s: tdlsLinkEstablishParams of peer "
18210 MAC_ADDRESS_STR "uapsdQueues: %d"
18211 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
18212 "isResponder: %d peerstaId: %d",
18213 __func__,
18214 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
18215 tdlsLinkEstablishParams.uapsdQueues,
18216 tdlsLinkEstablishParams.qos,
18217 tdlsLinkEstablishParams.maxSp,
18218 tdlsLinkEstablishParams.isBufSta,
18219 tdlsLinkEstablishParams.isOffChannelSupported,
18220 tdlsLinkEstablishParams.isResponder,
18221 pTdlsPeer->staId);
18222
18223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18224 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
18225 __func__,
18226 staDesc.ucSTAId,
18227 staDesc.ucQosEnabled);
18228
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018229 ret = WLANTL_UpdateTdlsSTAClient(
18230 pHddCtx->pvosContext,
18231 &staDesc);
18232 if (ret != VOS_STATUS_SUCCESS) {
18233 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
18234 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053018235
Gopichand Nakkala471708b2013-06-04 20:03:01 +053018236 /* Mark TDLS client Authenticated .*/
18237 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
18238 pTdlsPeer->staId,
18239 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018240 if (VOS_STATUS_SUCCESS == status)
18241 {
Hoonki Lee14621352013-04-16 17:51:19 -070018242 if (pTdlsPeer->is_responder == 0)
18243 {
18244 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018245 tdlsConnInfo_t *tdlsInfo;
18246
18247 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
18248
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018249 if (!vos_timer_is_initialized(
18250 &pTdlsPeer->initiatorWaitTimeoutTimer))
18251 {
18252 /* Initialize initiator wait callback */
18253 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018254 &pTdlsPeer->initiatorWaitTimeoutTimer,
18255 VOS_TIMER_TYPE_SW,
18256 wlan_hdd_tdls_initiator_wait_cb,
18257 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018258 }
Hoonki Lee14621352013-04-16 17:51:19 -070018259 wlan_hdd_tdls_timer_restart(pAdapter,
18260 &pTdlsPeer->initiatorWaitTimeoutTimer,
18261 WAIT_TIME_TDLS_INITIATOR);
18262 /* suspend initiator TX until it receives direct packet from the
18263 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018264 ret = WLANTL_SuspendDataTx(
18265 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18266 &staId, NULL);
18267 if (ret != VOS_STATUS_SUCCESS) {
18268 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
18269 }
Hoonki Lee14621352013-04-16 17:51:19 -070018270 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018271
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018272 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018273 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018274 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018275 suppChannelLen =
18276 tdlsLinkEstablishParams.supportedChannelsLen;
18277
18278 if ((suppChannelLen > 0) &&
18279 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
18280 {
18281 tANI_U8 suppPeerChannel = 0;
18282 int i = 0;
18283 for (i = 0U; i < suppChannelLen; i++)
18284 {
18285 suppPeerChannel =
18286 tdlsLinkEstablishParams.supportedChannels[i];
18287
18288 pTdlsPeer->isOffChannelSupported = FALSE;
18289 if (suppPeerChannel ==
18290 pTdlsPeer->peerParams.channel)
18291 {
18292 pTdlsPeer->isOffChannelSupported = TRUE;
18293 break;
18294 }
18295 }
18296 }
18297 else
18298 {
18299 pTdlsPeer->isOffChannelSupported = FALSE;
18300 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018301 }
18302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18303 "%s: TDLS channel switch request for channel "
18304 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018305 "%d isOffChannelSupported %d", __func__,
18306 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018307 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018308 suppChannelLen,
18309 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018310
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018311 /* TDLS Off Channel, Enable tdls channel switch,
18312 when their is only one tdls link and it supports */
18313 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18314 if ((numCurrTdlsPeers == 1) &&
18315 (TRUE == pTdlsPeer->isOffChannelSupported) &&
18316 (TRUE == pTdlsPeer->isOffChannelConfigured))
18317 {
18318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18319 "%s: Send TDLS channel switch request for channel %d",
18320 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018321
18322 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018323 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
18324 channel = pTdlsPeer->peerParams.channel;
18325
18326 mutex_unlock(&pHddCtx->tdls_lock);
18327
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018328 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
18329 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018330 peerMac,
18331 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018332 TDLS_OFF_CHANNEL_BW_OFFSET,
18333 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018334 if (ret != VOS_STATUS_SUCCESS) {
18335 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
18336 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018337 }
18338 else
18339 {
18340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18341 "%s: TDLS channel switch request not sent"
18342 " numCurrTdlsPeers %d "
18343 "isOffChannelSupported %d "
18344 "isOffChannelConfigured %d",
18345 __func__, numCurrTdlsPeers,
18346 pTdlsPeer->isOffChannelSupported,
18347 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018348 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018349 }
18350
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018351 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018352 else
18353 mutex_unlock(&pHddCtx->tdls_lock);
18354
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018355 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018356
18357 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018358 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18359 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018360 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018361 int ac;
18362 uint8 ucAc[4] = { WLANTL_AC_VO,
18363 WLANTL_AC_VI,
18364 WLANTL_AC_BK,
18365 WLANTL_AC_BE };
18366 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18367 for(ac=0; ac < 4; ac++)
18368 {
18369 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18370 pTdlsPeer->staId, ucAc[ac],
18371 tlTid[ac], tlTid[ac], 0, 0,
18372 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018373 if (status != VOS_STATUS_SUCCESS) {
18374 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18375 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018376 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018377 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018378 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018379
Bhargav Shah66896792015-10-01 18:17:37 +053018380 /* stop TCP delack timer if TDLS is enable */
18381 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18382 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053018383 hdd_wlan_tdls_enable_link_event(peer,
18384 pTdlsPeer->isOffChannelSupported,
18385 pTdlsPeer->isOffChannelConfigured,
18386 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018387 }
18388 break;
18389 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018390 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018391 tANI_U16 numCurrTdlsPeers = 0;
18392 hddTdlsPeer_t *connPeer = NULL;
18393
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18395 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18396 __func__, MAC_ADDR_ARRAY(peer));
18397
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018398 mutex_lock(&pHddCtx->tdls_lock);
18399 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018400
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018401
Sunil Dutt41de4e22013-11-14 18:09:02 +053018402 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018403 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018404 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18405 " (oper %d) not exsting. ignored",
18406 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18407 return -EINVAL;
18408 }
18409
18410 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18411 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18412 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18413 "NL80211_TDLS_DISABLE_LINK");
18414
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018415 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018416 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018417 long status;
18418
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018419 /* set tdls off channel status to false for this peer */
18420 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018421 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18422 eTDLS_LINK_TEARING,
18423 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18424 eTDLS_LINK_UNSPECIFIED:
18425 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018426 mutex_unlock(&pHddCtx->tdls_lock);
18427
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018428 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18429
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018430 status = sme_DeleteTdlsPeerSta(
18431 WLAN_HDD_GET_HAL_CTX(pAdapter),
18432 pAdapter->sessionId, peer );
18433 if (status != VOS_STATUS_SUCCESS) {
18434 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18435 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018436
18437 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18438 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018439
18440 mutex_lock(&pHddCtx->tdls_lock);
18441 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18442 if ( NULL == pTdlsPeer ) {
18443 mutex_unlock(&pHddCtx->tdls_lock);
18444 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18445 " peer was freed in other context",
18446 __func__, MAC_ADDR_ARRAY(peer));
18447 return -EINVAL;
18448 }
18449
Atul Mittal271a7652014-09-12 13:18:22 +053018450 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053018451 eTDLS_LINK_IDLE,
18452 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018453 mutex_unlock(&pHddCtx->tdls_lock);
18454
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018455 if (status <= 0)
18456 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18458 "%s: Del station failed status %ld",
18459 __func__, status);
18460 return -EPERM;
18461 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018462
18463 /* TDLS Off Channel, Enable tdls channel switch,
18464 when their is only one tdls link and it supports */
18465 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18466 if (numCurrTdlsPeers == 1)
18467 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018468 tSirMacAddr peerMac;
18469 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018470
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018471 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018472 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018473
18474 if (connPeer == NULL) {
18475 mutex_unlock(&pHddCtx->tdls_lock);
18476 hddLog(VOS_TRACE_LEVEL_ERROR,
18477 "%s connPeer is NULL", __func__);
18478 return -EINVAL;
18479 }
18480
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018481 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18482 channel = connPeer->peerParams.channel;
18483
18484 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18485 "%s: TDLS channel switch "
18486 "isOffChannelSupported %d "
18487 "isOffChannelConfigured %d "
18488 "isOffChannelEstablished %d",
18489 __func__,
18490 (connPeer ? connPeer->isOffChannelSupported : -1),
18491 (connPeer ? connPeer->isOffChannelConfigured : -1),
18492 (connPeer ? connPeer->isOffChannelEstablished : -1));
18493
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018494 if ((connPeer) &&
18495 (connPeer->isOffChannelSupported == TRUE) &&
18496 (connPeer->isOffChannelConfigured == TRUE))
18497 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018498 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018499 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018500 status = sme_SendTdlsChanSwitchReq(
18501 WLAN_HDD_GET_HAL_CTX(pAdapter),
18502 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018503 peerMac,
18504 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018505 TDLS_OFF_CHANNEL_BW_OFFSET,
18506 TDLS_CHANNEL_SWITCH_ENABLE);
18507 if (status != VOS_STATUS_SUCCESS) {
18508 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18509 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018510 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018511 else
18512 mutex_unlock(&pHddCtx->tdls_lock);
18513 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018514 else
18515 {
18516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18517 "%s: TDLS channel switch request not sent "
18518 "numCurrTdlsPeers %d ",
18519 __func__, numCurrTdlsPeers);
18520 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018521 }
18522 else
18523 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018524 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18526 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080018527 }
Bhargav Shah66896792015-10-01 18:17:37 +053018528 if (numCurrTdlsPeers == 0) {
18529 /* start TCP delack timer if TDLS is disable */
18530 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18531 hdd_manage_delack_timer(pHddCtx);
18532 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018533 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018534 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018535 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018536 {
Atul Mittal115287b2014-07-08 13:26:33 +053018537 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018538
Atul Mittal115287b2014-07-08 13:26:33 +053018539 if (0 != status)
18540 {
18541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018542 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053018543 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018544 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053018545 break;
18546 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018547 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018548 {
Atul Mittal115287b2014-07-08 13:26:33 +053018549 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
18550 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018551 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053018552 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018553
Atul Mittal115287b2014-07-08 13:26:33 +053018554 if (0 != status)
18555 {
18556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018557 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053018558 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053018559 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053018560 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018561 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018562 case NL80211_TDLS_DISCOVERY_REQ:
18563 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018565 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018566 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018567 return -ENOTSUPP;
18568 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18570 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018571 return -ENOTSUPP;
18572 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018573
18574 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018575 return 0;
18576}
Chilam NG571c65a2013-01-19 12:27:36 +053018577
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018578static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018579#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18580 const u8 *peer,
18581#else
18582 u8 *peer,
18583#endif
18584 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018585{
18586 int ret;
18587
18588 vos_ssr_protect(__func__);
18589 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
18590 vos_ssr_unprotect(__func__);
18591
18592 return ret;
18593}
18594
Chilam NG571c65a2013-01-19 12:27:36 +053018595int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
18596 struct net_device *dev, u8 *peer)
18597{
Arif Hussaina7c8e412013-11-20 11:06:42 -080018598 hddLog(VOS_TRACE_LEVEL_INFO,
18599 "tdls send discover req: "MAC_ADDRESS_STR,
18600 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018601#if TDLS_MGMT_VERSION2
18602 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18603 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18604#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018605#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18606 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18607 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
18608#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18609 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18610 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18611#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18612 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18613 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18614#else
Chilam NG571c65a2013-01-19 12:27:36 +053018615 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18616 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018617#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018618#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053018619}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018620#endif
18621
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018622#ifdef WLAN_FEATURE_GTK_OFFLOAD
18623/*
18624 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
18625 * Callback rountine called upon receiving response for
18626 * get offload info
18627 */
18628void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
18629 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
18630{
18631
18632 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018633 tANI_U8 tempReplayCounter[8];
18634 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018635
18636 ENTER();
18637
18638 if (NULL == pAdapter)
18639 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018641 "%s: HDD adapter is Null", __func__);
18642 return ;
18643 }
18644
18645 if (NULL == pGtkOffloadGetInfoRsp)
18646 {
18647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18648 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
18649 return ;
18650 }
18651
18652 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
18653 {
18654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18655 "%s: wlan Failed to get replay counter value",
18656 __func__);
18657 return ;
18658 }
18659
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018660 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18661 /* Update replay counter */
18662 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
18663 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18664
18665 {
18666 /* changing from little to big endian since supplicant
18667 * works on big endian format
18668 */
18669 int i;
18670 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18671
18672 for (i = 0; i < 8; i++)
18673 {
18674 tempReplayCounter[7-i] = (tANI_U8)p[i];
18675 }
18676 }
18677
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018678 /* Update replay counter to NL */
18679 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018680 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018681}
18682
18683/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018684 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018685 * This function is used to offload GTK rekeying job to the firmware.
18686 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018687int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018688 struct cfg80211_gtk_rekey_data *data)
18689{
18690 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18691 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18692 hdd_station_ctx_t *pHddStaCtx;
18693 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018694 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018695 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018696 eHalStatus status = eHAL_STATUS_FAILURE;
18697
18698 ENTER();
18699
18700 if (NULL == pAdapter)
18701 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018703 "%s: HDD adapter is Null", __func__);
18704 return -ENODEV;
18705 }
18706
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018707 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18708 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
18709 pAdapter->sessionId, pAdapter->device_mode));
18710
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018711 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018712 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018713 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018714 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018715 }
18716
18717 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18718 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18719 if (NULL == hHal)
18720 {
18721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18722 "%s: HAL context is Null!!!", __func__);
18723 return -EAGAIN;
18724 }
18725
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018726 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
18727 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
18728 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
18729 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018730 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018731 {
18732 /* changing from big to little endian since driver
18733 * works on little endian format
18734 */
18735 tANI_U8 *p =
18736 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
18737 int i;
18738
18739 for (i = 0; i < 8; i++)
18740 {
18741 p[7-i] = data->replay_ctr[i];
18742 }
18743 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018744
18745 if (TRUE == pHddCtx->hdd_wlan_suspended)
18746 {
18747 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018748 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
18749 sizeof (tSirGtkOffloadParams));
18750 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018751 pAdapter->sessionId);
18752
18753 if (eHAL_STATUS_SUCCESS != status)
18754 {
18755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18756 "%s: sme_SetGTKOffload failed, returned %d",
18757 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018758
18759 /* Need to clear any trace of key value in the memory.
18760 * Thus zero out the memory even though it is local
18761 * variable.
18762 */
18763 vos_mem_zero(&hddGtkOffloadReqParams,
18764 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018765 return status;
18766 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18768 "%s: sme_SetGTKOffload successfull", __func__);
18769 }
18770 else
18771 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18773 "%s: wlan not suspended GTKOffload request is stored",
18774 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018775 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018776
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018777 /* Need to clear any trace of key value in the memory.
18778 * Thus zero out the memory even though it is local
18779 * variable.
18780 */
18781 vos_mem_zero(&hddGtkOffloadReqParams,
18782 sizeof(hddGtkOffloadReqParams));
18783
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018784 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018785 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018786}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018787
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018788int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
18789 struct cfg80211_gtk_rekey_data *data)
18790{
18791 int ret;
18792
18793 vos_ssr_protect(__func__);
18794 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
18795 vos_ssr_unprotect(__func__);
18796
18797 return ret;
18798}
18799#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018800/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018801 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018802 * This function is used to set access control policy
18803 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018804static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18805 struct net_device *dev,
18806 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018807{
18808 int i;
18809 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18810 hdd_hostapd_state_t *pHostapdState;
18811 tsap_Config_t *pConfig;
18812 v_CONTEXT_t pVosContext = NULL;
18813 hdd_context_t *pHddCtx;
18814 int status;
18815
18816 ENTER();
18817
18818 if (NULL == pAdapter)
18819 {
18820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18821 "%s: HDD adapter is Null", __func__);
18822 return -ENODEV;
18823 }
18824
18825 if (NULL == params)
18826 {
18827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18828 "%s: params is Null", __func__);
18829 return -EINVAL;
18830 }
18831
18832 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18833 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018834 if (0 != status)
18835 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018836 return status;
18837 }
18838
18839 pVosContext = pHddCtx->pvosContext;
18840 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
18841
18842 if (NULL == pHostapdState)
18843 {
18844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18845 "%s: pHostapdState is Null", __func__);
18846 return -EINVAL;
18847 }
18848
18849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
18850 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018851 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18852 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
18853 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018854
18855 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
18856 {
18857 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
18858
18859 /* default value */
18860 pConfig->num_accept_mac = 0;
18861 pConfig->num_deny_mac = 0;
18862
18863 /**
18864 * access control policy
18865 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
18866 * listed in hostapd.deny file.
18867 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
18868 * listed in hostapd.accept file.
18869 */
18870 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
18871 {
18872 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
18873 }
18874 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
18875 {
18876 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
18877 }
18878 else
18879 {
18880 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18881 "%s:Acl Policy : %d is not supported",
18882 __func__, params->acl_policy);
18883 return -ENOTSUPP;
18884 }
18885
18886 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
18887 {
18888 pConfig->num_accept_mac = params->n_acl_entries;
18889 for (i = 0; i < params->n_acl_entries; i++)
18890 {
18891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18892 "** Add ACL MAC entry %i in WhiletList :"
18893 MAC_ADDRESS_STR, i,
18894 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18895
18896 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
18897 sizeof(qcmacaddr));
18898 }
18899 }
18900 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
18901 {
18902 pConfig->num_deny_mac = params->n_acl_entries;
18903 for (i = 0; i < params->n_acl_entries; i++)
18904 {
18905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18906 "** Add ACL MAC entry %i in BlackList :"
18907 MAC_ADDRESS_STR, i,
18908 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18909
18910 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
18911 sizeof(qcmacaddr));
18912 }
18913 }
18914
18915 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
18916 {
18917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18918 "%s: SAP Set Mac Acl fail", __func__);
18919 return -EINVAL;
18920 }
18921 }
18922 else
18923 {
18924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053018925 "%s: Invalid device_mode = %s (%d)",
18926 __func__, hdd_device_modetoString(pAdapter->device_mode),
18927 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018928 return -EINVAL;
18929 }
18930
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018931 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018932 return 0;
18933}
18934
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018935static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18936 struct net_device *dev,
18937 const struct cfg80211_acl_data *params)
18938{
18939 int ret;
18940 vos_ssr_protect(__func__);
18941 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
18942 vos_ssr_unprotect(__func__);
18943
18944 return ret;
18945}
18946
Leo Chang9056f462013-08-01 19:21:11 -070018947#ifdef WLAN_NL80211_TESTMODE
18948#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070018949void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070018950(
18951 void *pAdapter,
18952 void *indCont
18953)
18954{
Leo Changd9df8aa2013-09-26 13:32:26 -070018955 tSirLPHBInd *lphbInd;
18956 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053018957 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070018958
18959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018960 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070018961
c_hpothu73f35e62014-04-18 13:40:08 +053018962 if (pAdapter == NULL)
18963 {
18964 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18965 "%s: pAdapter is NULL\n",__func__);
18966 return;
18967 }
18968
Leo Chang9056f462013-08-01 19:21:11 -070018969 if (NULL == indCont)
18970 {
18971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018972 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070018973 return;
18974 }
18975
c_hpothu73f35e62014-04-18 13:40:08 +053018976 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070018977 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070018978 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053018979 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070018980 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070018981 GFP_ATOMIC);
18982 if (!skb)
18983 {
18984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18985 "LPHB timeout, NL buffer alloc fail");
18986 return;
18987 }
18988
Leo Changac3ba772013-10-07 09:47:04 -070018989 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070018990 {
18991 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18992 "WLAN_HDD_TM_ATTR_CMD put fail");
18993 goto nla_put_failure;
18994 }
Leo Changac3ba772013-10-07 09:47:04 -070018995 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070018996 {
18997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18998 "WLAN_HDD_TM_ATTR_TYPE put fail");
18999 goto nla_put_failure;
19000 }
Leo Changac3ba772013-10-07 09:47:04 -070019001 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070019002 sizeof(tSirLPHBInd), lphbInd))
19003 {
19004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19005 "WLAN_HDD_TM_ATTR_DATA put fail");
19006 goto nla_put_failure;
19007 }
Leo Chang9056f462013-08-01 19:21:11 -070019008 cfg80211_testmode_event(skb, GFP_ATOMIC);
19009 return;
19010
19011nla_put_failure:
19012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19013 "NLA Put fail");
19014 kfree_skb(skb);
19015
19016 return;
19017}
19018#endif /* FEATURE_WLAN_LPHB */
19019
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019020static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070019021{
19022 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
19023 int err = 0;
19024#ifdef FEATURE_WLAN_LPHB
19025 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070019026 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019027
19028 ENTER();
19029
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019030 err = wlan_hdd_validate_context(pHddCtx);
19031 if (0 != err)
19032 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019033 return err;
19034 }
Leo Chang9056f462013-08-01 19:21:11 -070019035#endif /* FEATURE_WLAN_LPHB */
19036
19037 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
19038 if (err)
19039 {
19040 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19041 "%s Testmode INV ATTR", __func__);
19042 return err;
19043 }
19044
19045 if (!tb[WLAN_HDD_TM_ATTR_CMD])
19046 {
19047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19048 "%s Testmode INV CMD", __func__);
19049 return -EINVAL;
19050 }
19051
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019052 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19053 TRACE_CODE_HDD_CFG80211_TESTMODE,
19054 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070019055 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
19056 {
19057#ifdef FEATURE_WLAN_LPHB
19058 /* Low Power Heartbeat configuration request */
19059 case WLAN_HDD_TM_CMD_WLAN_HB:
19060 {
19061 int buf_len;
19062 void *buf;
19063 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080019064 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070019065
19066 if (!tb[WLAN_HDD_TM_ATTR_DATA])
19067 {
19068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19069 "%s Testmode INV DATA", __func__);
19070 return -EINVAL;
19071 }
19072
19073 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
19074 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080019075
19076 hb_params_temp =(tSirLPHBReq *)buf;
19077 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
19078 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
19079 return -EINVAL;
19080
Leo Chang9056f462013-08-01 19:21:11 -070019081 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
19082 if (NULL == hb_params)
19083 {
19084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19085 "%s Request Buffer Alloc Fail", __func__);
19086 return -EINVAL;
19087 }
19088
19089 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070019090 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
19091 hb_params,
19092 wlan_hdd_cfg80211_lphb_ind_handler);
19093 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070019094 {
Leo Changd9df8aa2013-09-26 13:32:26 -070019095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19096 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070019097 vos_mem_free(hb_params);
19098 }
Leo Chang9056f462013-08-01 19:21:11 -070019099 return 0;
19100 }
19101#endif /* FEATURE_WLAN_LPHB */
19102 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19104 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070019105 return -EOPNOTSUPP;
19106 }
19107
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019108 EXIT();
19109 return err;
Leo Chang9056f462013-08-01 19:21:11 -070019110}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019111
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053019112static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
19113#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
19114 struct wireless_dev *wdev,
19115#endif
19116 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019117{
19118 int ret;
19119
19120 vos_ssr_protect(__func__);
19121 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
19122 vos_ssr_unprotect(__func__);
19123
19124 return ret;
19125}
Leo Chang9056f462013-08-01 19:21:11 -070019126#endif /* CONFIG_NL80211_TESTMODE */
19127
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019128static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019129 struct net_device *dev,
19130 int idx, struct survey_info *survey)
19131{
19132 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19133 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053019134 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019135 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053019136 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019137 v_S7_t snr,rssi;
19138 int status, i, j, filled = 0;
19139
19140 ENTER();
19141
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019142 if (NULL == pAdapter)
19143 {
19144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19145 "%s: HDD adapter is Null", __func__);
19146 return -ENODEV;
19147 }
19148
19149 if (NULL == wiphy)
19150 {
19151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19152 "%s: wiphy is Null", __func__);
19153 return -ENODEV;
19154 }
19155
19156 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19157 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019158 if (0 != status)
19159 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019160 return status;
19161 }
19162
Mihir Sheted9072e02013-08-21 17:02:29 +053019163 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19164
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019165 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053019166 0 != pAdapter->survey_idx ||
19167 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019168 {
19169 /* The survey dump ops when implemented completely is expected to
19170 * return a survey of all channels and the ops is called by the
19171 * kernel with incremental values of the argument 'idx' till it
19172 * returns -ENONET. But we can only support the survey for the
19173 * operating channel for now. survey_idx is used to track
19174 * that the ops is called only once and then return -ENONET for
19175 * the next iteration
19176 */
19177 pAdapter->survey_idx = 0;
19178 return -ENONET;
19179 }
19180
Mukul Sharma9d5233b2015-06-11 20:28:20 +053019181 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
19182 {
19183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19184 "%s: Roaming in progress, hence return ", __func__);
19185 return -ENONET;
19186 }
19187
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019188 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19189
19190 wlan_hdd_get_snr(pAdapter, &snr);
19191 wlan_hdd_get_rssi(pAdapter, &rssi);
19192
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019193 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19194 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
19195 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019196 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
19197 hdd_wlan_get_freq(channel, &freq);
19198
19199
19200 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
19201 {
19202 if (NULL == wiphy->bands[i])
19203 {
19204 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
19205 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
19206 continue;
19207 }
19208
19209 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
19210 {
19211 struct ieee80211_supported_band *band = wiphy->bands[i];
19212
19213 if (band->channels[j].center_freq == (v_U16_t)freq)
19214 {
19215 survey->channel = &band->channels[j];
19216 /* The Rx BDs contain SNR values in dB for the received frames
19217 * while the supplicant expects noise. So we calculate and
19218 * return the value of noise (dBm)
19219 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
19220 */
19221 survey->noise = rssi - snr;
19222 survey->filled = SURVEY_INFO_NOISE_DBM;
19223 filled = 1;
19224 }
19225 }
19226 }
19227
19228 if (filled)
19229 pAdapter->survey_idx = 1;
19230 else
19231 {
19232 pAdapter->survey_idx = 0;
19233 return -ENONET;
19234 }
19235
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019236 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019237 return 0;
19238}
19239
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019240static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
19241 struct net_device *dev,
19242 int idx, struct survey_info *survey)
19243{
19244 int ret;
19245
19246 vos_ssr_protect(__func__);
19247 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
19248 vos_ssr_unprotect(__func__);
19249
19250 return ret;
19251}
19252
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019253/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019254 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019255 * this is called when cfg80211 driver resume
19256 * driver updates latest sched_scan scan result(if any) to cfg80211 database
19257 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019258int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019259{
19260 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19261 hdd_adapter_t *pAdapter;
19262 hdd_adapter_list_node_t *pAdapterNode, *pNext;
19263 VOS_STATUS status = VOS_STATUS_SUCCESS;
19264
19265 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019266
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019267 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019268 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019269 return 0;
19270 }
19271
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019272 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
19273 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019274 spin_lock(&pHddCtx->schedScan_lock);
19275 pHddCtx->isWiphySuspended = FALSE;
19276 if (TRUE != pHddCtx->isSchedScanUpdatePending)
19277 {
19278 spin_unlock(&pHddCtx->schedScan_lock);
19279 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19280 "%s: Return resume is not due to PNO indication", __func__);
19281 return 0;
19282 }
19283 // Reset flag to avoid updatating cfg80211 data old results again
19284 pHddCtx->isSchedScanUpdatePending = FALSE;
19285 spin_unlock(&pHddCtx->schedScan_lock);
19286
19287 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
19288
19289 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
19290 {
19291 pAdapter = pAdapterNode->pAdapter;
19292 if ( (NULL != pAdapter) &&
19293 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
19294 {
19295 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019296 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19298 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019299 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019300 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019301 {
19302 /* Acquire wakelock to handle the case where APP's tries to
19303 * suspend immediately after updating the scan results. Whis
19304 * results in app's is in suspended state and not able to
19305 * process the connect request to AP
19306 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053019307 hdd_prevent_suspend_timeout(2000,
19308 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019309 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019310 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019311
19312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19313 "%s : cfg80211 scan result database updated", __func__);
19314
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019315 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019316 return 0;
19317
19318 }
19319 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19320 pAdapterNode = pNext;
19321 }
19322
19323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19324 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019325 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019326 return 0;
19327}
19328
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019329int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
19330{
19331 int ret;
19332
19333 vos_ssr_protect(__func__);
19334 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
19335 vos_ssr_unprotect(__func__);
19336
19337 return ret;
19338}
19339
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019340/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019341 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019342 * this is called when cfg80211 driver suspends
19343 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019344int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019345 struct cfg80211_wowlan *wow)
19346{
19347 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019348 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019349
19350 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019351
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019352 ret = wlan_hdd_validate_context(pHddCtx);
19353 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019354 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019355 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019356 }
19357
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019358
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019359 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19360 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
19361 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019362 pHddCtx->isWiphySuspended = TRUE;
19363
19364 EXIT();
19365
19366 return 0;
19367}
19368
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019369int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19370 struct cfg80211_wowlan *wow)
19371{
19372 int ret;
19373
19374 vos_ssr_protect(__func__);
19375 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19376 vos_ssr_unprotect(__func__);
19377
19378 return ret;
19379}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019380
19381#ifdef FEATURE_OEM_DATA_SUPPORT
19382static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019383 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019384{
19385 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19386
19387 ENTER();
19388
19389 if (wlan_hdd_validate_context(pHddCtx)) {
19390 return;
19391 }
19392 if (!pMsg)
19393 {
19394 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
19395 return;
19396 }
19397
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019398 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019399
19400 EXIT();
19401 return;
19402
19403}
19404
19405void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019406 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019407{
19408 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19409
19410 ENTER();
19411
19412 if (wlan_hdd_validate_context(pHddCtx)) {
19413 return;
19414 }
19415
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019416 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019417
19418 switch(evType) {
19419 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019420 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019421 break;
19422 default:
19423 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
19424 break;
19425 }
19426 EXIT();
19427}
19428#endif
19429
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019430#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19431 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019432/**
19433 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
19434 * @wiphy: Pointer to wiphy
19435 * @wdev: Pointer to wireless device structure
19436 *
19437 * This function is used to abort an ongoing scan
19438 *
19439 * Return: None
19440 */
19441static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19442 struct wireless_dev *wdev)
19443{
19444 struct net_device *dev = wdev->netdev;
19445 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
19446 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
19447 int ret;
19448
19449 ENTER();
19450
19451 if (NULL == adapter) {
19452 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
19453 return;
19454 }
19455
19456 ret = wlan_hdd_validate_context(hdd_ctx);
19457 if (0 != ret)
19458 return;
19459
19460 wlan_hdd_scan_abort(adapter);
19461
19462 return;
19463}
19464
19465/**
19466 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
19467 * @wiphy: Pointer to wiphy
19468 * @wdev: Pointer to wireless device structure
19469 *
19470 * Return: None
19471 */
19472void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19473 struct wireless_dev *wdev)
19474{
19475 vos_ssr_protect(__func__);
19476 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
19477 vos_ssr_unprotect(__func__);
19478
19479 return;
19480}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019481#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019482
Jeff Johnson295189b2012-06-20 16:38:30 -070019483/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019484static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070019485{
19486 .add_virtual_intf = wlan_hdd_add_virtual_intf,
19487 .del_virtual_intf = wlan_hdd_del_virtual_intf,
19488 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
19489 .change_station = wlan_hdd_change_station,
19490#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
19491 .add_beacon = wlan_hdd_cfg80211_add_beacon,
19492 .del_beacon = wlan_hdd_cfg80211_del_beacon,
19493 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019494#else
19495 .start_ap = wlan_hdd_cfg80211_start_ap,
19496 .change_beacon = wlan_hdd_cfg80211_change_beacon,
19497 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070019498#endif
19499 .change_bss = wlan_hdd_cfg80211_change_bss,
19500 .add_key = wlan_hdd_cfg80211_add_key,
19501 .get_key = wlan_hdd_cfg80211_get_key,
19502 .del_key = wlan_hdd_cfg80211_del_key,
19503 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019504#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070019505 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019506#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019507 .scan = wlan_hdd_cfg80211_scan,
19508 .connect = wlan_hdd_cfg80211_connect,
19509 .disconnect = wlan_hdd_cfg80211_disconnect,
19510 .join_ibss = wlan_hdd_cfg80211_join_ibss,
19511 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
19512 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
19513 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
19514 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070019515 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
19516 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053019517 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070019518#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19519 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
19520 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
19521 .set_txq_params = wlan_hdd_set_txq_params,
19522#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019523 .get_station = wlan_hdd_cfg80211_get_station,
19524 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
19525 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019526 .add_station = wlan_hdd_cfg80211_add_station,
19527#ifdef FEATURE_WLAN_LFR
19528 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
19529 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
19530 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
19531#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019532#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
19533 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
19534#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019535#ifdef FEATURE_WLAN_TDLS
19536 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
19537 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
19538#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019539#ifdef WLAN_FEATURE_GTK_OFFLOAD
19540 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
19541#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019542#ifdef FEATURE_WLAN_SCAN_PNO
19543 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
19544 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
19545#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019546 .resume = wlan_hdd_cfg80211_resume_wlan,
19547 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019548 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070019549#ifdef WLAN_NL80211_TESTMODE
19550 .testmode_cmd = wlan_hdd_cfg80211_testmode,
19551#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019552 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019553#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19554 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019555 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019556#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019557};
19558