blob: 1158afd3bd9633c7994fe56243c7862c794dc23a [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{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304211 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4212 struct net_device *dev = wdev->netdev;
4213 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4214 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4215 uint8_t num_channels = 0;
4216 uint8_t num_chan_new = 0;
4217 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304218 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304219 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304220 tWifiBand wifiBand;
4221 eHalStatus status;
4222 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304223 tANI_U8 i,j,k;
4224 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304225
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304226 ENTER();
4227
Dino Mycle6fb96c12014-06-10 11:52:40 +05304228 status = wlan_hdd_validate_context(pHddCtx);
4229 if (0 != status)
4230 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304231 return -EINVAL;
4232 }
Dino Myclee8843b32014-07-04 14:21:45 +05304233
Dino Mycle6fb96c12014-06-10 11:52:40 +05304234 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4235 data, dataLen,
4236 wlan_hdd_extscan_config_policy)) {
4237 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4238 return -EINVAL;
4239 }
4240
4241 /* Parse and fetch request Id */
4242 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4243 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4244 return -EINVAL;
4245 }
4246 requestId = nla_get_u32(
4247 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4248 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4249
4250 /* Parse and fetch wifi band */
4251 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4252 {
4253 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4254 return -EINVAL;
4255 }
4256 wifiBand = nla_get_u32(
4257 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4258 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4259
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304260 /* Parse and fetch max channels */
4261 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4262 {
4263 hddLog(LOGE, FL("attr max channels failed"));
4264 return -EINVAL;
4265 }
4266 maxChannels = nla_get_u32(
4267 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4268 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4269
Dino Mycle6fb96c12014-06-10 11:52:40 +05304270 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304271 wifiBand, chan_list,
4272 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304273 if (eHAL_STATUS_SUCCESS != status) {
4274 hddLog(VOS_TRACE_LEVEL_ERROR,
4275 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4276 return -EINVAL;
4277 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304278
Agrawal Ashish16abf782016-08-18 22:42:59 +05304279 num_channels = VOS_MIN(num_channels, maxChannels);
4280 num_chan_new = num_channels;
4281 /* remove the indoor only channels if iface is SAP */
4282 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4283 {
4284 num_chan_new = 0;
4285 for (i = 0; i < num_channels; i++)
4286 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
4287 if (wiphy->bands[j] == NULL)
4288 continue;
4289 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4290 if ((chan_list[i] ==
4291 wiphy->bands[j]->channels[k].center_freq) &&
4292 (!(wiphy->bands[j]->channels[k].flags &
4293 IEEE80211_CHAN_INDOOR_ONLY))) {
4294 chan_list[num_chan_new] = chan_list[i];
4295 num_chan_new++;
4296 }
4297 }
4298 }
4299 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304300
Agrawal Ashish16abf782016-08-18 22:42:59 +05304301 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4302 for (i = 0; i < num_chan_new; i++)
4303 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4304 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304305
4306 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304307 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304308 NLMSG_HDRLEN);
4309
4310 if (!replySkb) {
4311 hddLog(VOS_TRACE_LEVEL_ERROR,
4312 FL("valid channels: buffer alloc fail"));
4313 return -EINVAL;
4314 }
4315 if (nla_put_u32(replySkb,
4316 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304317 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304318 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304319 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304320
4321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4322 kfree_skb(replySkb);
4323 return -EINVAL;
4324 }
4325
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304326 ret = cfg80211_vendor_cmd_reply(replySkb);
4327
4328 EXIT();
4329 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304330}
4331
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304332static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4333 struct wireless_dev *wdev,
4334 const void *data, int dataLen)
4335{
4336 int ret = 0;
4337
4338 vos_ssr_protect(__func__);
4339 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4340 dataLen);
4341 vos_ssr_unprotect(__func__);
4342
4343 return ret;
4344}
4345
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304346static int hdd_extscan_start_fill_bucket_channel_spec(
4347 hdd_context_t *pHddCtx,
4348 tpSirEXTScanStartReqParams pReqMsg,
4349 struct nlattr **tb)
4350{
4351 struct nlattr *bucket[
4352 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4353 struct nlattr *channel[
4354 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4355 struct nlattr *buckets;
4356 struct nlattr *channels;
4357 int rem1, rem2;
4358 eHalStatus status;
4359 tANI_U8 bktIndex, j, numChannels;
4360 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4361 tANI_U32 passive_max_chn_time, active_max_chn_time;
4362
4363 bktIndex = 0;
4364
4365 nla_for_each_nested(buckets,
4366 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4367 if (nla_parse(bucket,
4368 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4369 nla_data(buckets), nla_len(buckets), NULL)) {
4370 hddLog(LOGE, FL("nla_parse failed"));
4371 return -EINVAL;
4372 }
4373
4374 /* Parse and fetch bucket spec */
4375 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4376 hddLog(LOGE, FL("attr bucket index failed"));
4377 return -EINVAL;
4378 }
4379 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4380 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4381 hddLog(LOG1, FL("Bucket spec Index %d"),
4382 pReqMsg->buckets[bktIndex].bucket);
4383
4384 /* Parse and fetch wifi band */
4385 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4386 hddLog(LOGE, FL("attr wifi band failed"));
4387 return -EINVAL;
4388 }
4389 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4390 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4391 hddLog(LOG1, FL("Wifi band %d"),
4392 pReqMsg->buckets[bktIndex].band);
4393
4394 /* Parse and fetch period */
4395 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4396 hddLog(LOGE, FL("attr period failed"));
4397 return -EINVAL;
4398 }
4399 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4400 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4401 hddLog(LOG1, FL("period %d"),
4402 pReqMsg->buckets[bktIndex].period);
4403
4404 /* Parse and fetch report events */
4405 if (!bucket[
4406 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4407 hddLog(LOGE, FL("attr report events failed"));
4408 return -EINVAL;
4409 }
4410 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4411 bucket[
4412 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4413 hddLog(LOG1, FL("report events %d"),
4414 pReqMsg->buckets[bktIndex].reportEvents);
4415
4416 /* Parse and fetch max period */
4417 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4418 hddLog(LOGE, FL("attr max period failed"));
4419 return -EINVAL;
4420 }
4421 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4422 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4423 hddLog(LOG1, FL("max period %u"),
4424 pReqMsg->buckets[bktIndex].max_period);
4425
4426 /* Parse and fetch exponent */
4427 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4428 hddLog(LOGE, FL("attr exponent failed"));
4429 return -EINVAL;
4430 }
4431 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4432 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4433 hddLog(LOG1, FL("exponent %u"),
4434 pReqMsg->buckets[bktIndex].exponent);
4435
4436 /* Parse and fetch step count */
4437 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4438 hddLog(LOGE, FL("attr step count failed"));
4439 return -EINVAL;
4440 }
4441 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4442 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4443 hddLog(LOG1, FL("Step count %u"),
4444 pReqMsg->buckets[bktIndex].step_count);
4445
4446 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4447 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4448
4449 /* Framework shall pass the channel list if the input WiFi band is
4450 * WIFI_BAND_UNSPECIFIED.
4451 * If the input WiFi band is specified (any value other than
4452 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4453 */
4454 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4455 numChannels = 0;
4456 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4457 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4458 pReqMsg->buckets[bktIndex].band,
4459 chanList, &numChannels);
4460 if (!HAL_STATUS_SUCCESS(status)) {
4461 hddLog(LOGE,
4462 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4463 status);
4464 return -EINVAL;
4465 }
4466
4467 pReqMsg->buckets[bktIndex].numChannels =
4468 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4469 hddLog(LOG1, FL("Num channels %d"),
4470 pReqMsg->buckets[bktIndex].numChannels);
4471
4472 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4473 j++) {
4474 pReqMsg->buckets[bktIndex].channels[j].channel =
4475 chanList[j];
4476 pReqMsg->buckets[bktIndex].channels[j].
4477 chnlClass = 0;
4478 if (CSR_IS_CHANNEL_DFS(
4479 vos_freq_to_chan(chanList[j]))) {
4480 pReqMsg->buckets[bktIndex].channels[j].
4481 passive = 1;
4482 pReqMsg->buckets[bktIndex].channels[j].
4483 dwellTimeMs = passive_max_chn_time;
4484 } else {
4485 pReqMsg->buckets[bktIndex].channels[j].
4486 passive = 0;
4487 pReqMsg->buckets[bktIndex].channels[j].
4488 dwellTimeMs = active_max_chn_time;
4489 }
4490
4491 hddLog(LOG1,
4492 "Channel %u Passive %u Dwell time %u ms",
4493 pReqMsg->buckets[bktIndex].channels[j].channel,
4494 pReqMsg->buckets[bktIndex].channels[j].passive,
4495 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4496 }
4497
4498 bktIndex++;
4499 continue;
4500 }
4501
4502 /* Parse and fetch number of channels */
4503 if (!bucket[
4504 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4505 hddLog(LOGE, FL("attr num channels failed"));
4506 return -EINVAL;
4507 }
4508
4509 pReqMsg->buckets[bktIndex].numChannels =
4510 nla_get_u32(bucket[
4511 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4512 hddLog(LOG1, FL("num channels %d"),
4513 pReqMsg->buckets[bktIndex].numChannels);
4514
4515 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4516 hddLog(LOGE, FL("attr channel spec failed"));
4517 return -EINVAL;
4518 }
4519
4520 j = 0;
4521 nla_for_each_nested(channels,
4522 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4523 if (nla_parse(channel,
4524 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4525 nla_data(channels), nla_len(channels),
4526 wlan_hdd_extscan_config_policy)) {
4527 hddLog(LOGE, FL("nla_parse failed"));
4528 return -EINVAL;
4529 }
4530
4531 /* Parse and fetch channel */
4532 if (!channel[
4533 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4534 hddLog(LOGE, FL("attr channel failed"));
4535 return -EINVAL;
4536 }
4537 pReqMsg->buckets[bktIndex].channels[j].channel =
4538 nla_get_u32(channel[
4539 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4540 hddLog(LOG1, FL("channel %u"),
4541 pReqMsg->buckets[bktIndex].channels[j].channel);
4542
4543 /* Parse and fetch dwell time */
4544 if (!channel[
4545 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4546 hddLog(LOGE, FL("attr dwelltime failed"));
4547 return -EINVAL;
4548 }
4549 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4550 nla_get_u32(channel[
4551 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4552
4553 hddLog(LOG1, FL("Dwell time (%u ms)"),
4554 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4555
4556
4557 /* Parse and fetch channel spec passive */
4558 if (!channel[
4559 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4560 hddLog(LOGE,
4561 FL("attr channel spec passive failed"));
4562 return -EINVAL;
4563 }
4564 pReqMsg->buckets[bktIndex].channels[j].passive =
4565 nla_get_u8(channel[
4566 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4567 hddLog(LOG1, FL("Chnl spec passive %u"),
4568 pReqMsg->buckets[bktIndex].channels[j].passive);
4569
4570 j++;
4571 }
4572
4573 bktIndex++;
4574 }
4575
4576 return 0;
4577}
4578
4579
4580/*
4581 * define short names for the global vendor params
4582 * used by wlan_hdd_cfg80211_extscan_start()
4583 */
4584#define PARAM_MAX \
4585QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4586#define PARAM_REQUEST_ID \
4587QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4588#define PARAM_BASE_PERIOD \
4589QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4590#define PARAM_MAX_AP_PER_SCAN \
4591QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4592#define PARAM_RPT_THRHLD_PERCENT \
4593QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4594#define PARAM_RPT_THRHLD_NUM_SCANS \
4595QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4596#define PARAM_NUM_BUCKETS \
4597QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4598
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304599static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304600 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304601 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304602{
Dino Myclee8843b32014-07-04 14:21:45 +05304603 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304604 struct net_device *dev = wdev->netdev;
4605 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4606 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4607 struct nlattr *tb[PARAM_MAX + 1];
4608 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304609 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304610 tANI_U32 request_id;
4611 struct hdd_ext_scan_context *context;
4612 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304613
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304614 ENTER();
4615
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304616 if (VOS_FTM_MODE == hdd_get_conparam()) {
4617 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4618 return -EINVAL;
4619 }
4620
Dino Mycle6fb96c12014-06-10 11:52:40 +05304621 status = wlan_hdd_validate_context(pHddCtx);
4622 if (0 != status)
4623 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304624 return -EINVAL;
4625 }
Dino Myclee8843b32014-07-04 14:21:45 +05304626 /* check the EXTScan Capability */
4627 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304628 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4629 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304630 {
4631 hddLog(VOS_TRACE_LEVEL_ERROR,
4632 FL("EXTScan not enabled/supported by Firmware"));
4633 return -EINVAL;
4634 }
4635
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304636 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304637 data, dataLen,
4638 wlan_hdd_extscan_config_policy)) {
4639 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4640 return -EINVAL;
4641 }
4642
4643 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304644 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304645 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4646 return -EINVAL;
4647 }
4648
Dino Myclee8843b32014-07-04 14:21:45 +05304649 pReqMsg = (tpSirEXTScanStartReqParams)
4650 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304651 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304652 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4653 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304654 }
4655
4656 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304657 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304658 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4659
4660 pReqMsg->sessionId = pAdapter->sessionId;
4661 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4662
4663 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304664 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304665 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4666 goto fail;
4667 }
4668 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304669 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304670 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4671 pReqMsg->basePeriod);
4672
4673 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304674 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4676 goto fail;
4677 }
4678 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304679 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304680 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4681 pReqMsg->maxAPperScan);
4682
4683 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304684 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4686 goto fail;
4687 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304688 pReqMsg->reportThresholdPercent = nla_get_u8(
4689 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304690 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304691 pReqMsg->reportThresholdPercent);
4692
4693 /* Parse and fetch report threshold num scans */
4694 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4695 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4696 goto fail;
4697 }
4698 pReqMsg->reportThresholdNumScans = nla_get_u8(
4699 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4700 hddLog(LOG1, FL("Report Threshold num scans %d"),
4701 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304702
4703 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304704 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304705 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4706 goto fail;
4707 }
4708 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304709 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304710 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4711 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4712 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4713 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4714 }
4715 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4716 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304717
Dino Mycle6fb96c12014-06-10 11:52:40 +05304718 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4719 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4720 goto fail;
4721 }
4722
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304723 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304724
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304725 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4726 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304727
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304728 context = &pHddCtx->ext_scan_context;
4729 spin_lock(&hdd_context_lock);
4730 INIT_COMPLETION(context->response_event);
4731 context->request_id = request_id = pReqMsg->requestId;
4732 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304733
Dino Mycle6fb96c12014-06-10 11:52:40 +05304734 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4735 if (!HAL_STATUS_SUCCESS(status)) {
4736 hddLog(VOS_TRACE_LEVEL_ERROR,
4737 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304738 goto fail;
4739 }
4740
Srinivas Dasari91727c12016-03-23 17:59:06 +05304741 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4742
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304743 /* request was sent -- wait for the response */
4744 rc = wait_for_completion_timeout(&context->response_event,
4745 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4746
4747 if (!rc) {
4748 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4749 retval = -ETIMEDOUT;
4750 } else {
4751 spin_lock(&hdd_context_lock);
4752 if (context->request_id == request_id)
4753 retval = context->response_status;
4754 else
4755 retval = -EINVAL;
4756 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304757 }
4758
Dino Myclee8843b32014-07-04 14:21:45 +05304759 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304760 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304761 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304762
4763fail:
4764 vos_mem_free(pReqMsg);
4765 return -EINVAL;
4766}
4767
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304768/*
4769 * done with short names for the global vendor params
4770 * used by wlan_hdd_cfg80211_extscan_start()
4771 */
4772#undef PARAM_MAX
4773#undef PARAM_REQUEST_ID
4774#undef PARAM_BASE_PERIOD
4775#undef PARAMS_MAX_AP_PER_SCAN
4776#undef PARAMS_RPT_THRHLD_PERCENT
4777#undef PARAMS_RPT_THRHLD_NUM_SCANS
4778#undef PARAMS_NUM_BUCKETS
4779
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304780static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4781 struct wireless_dev *wdev,
4782 const void *data, int dataLen)
4783{
4784 int ret = 0;
4785
4786 vos_ssr_protect(__func__);
4787 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4788 vos_ssr_unprotect(__func__);
4789
4790 return ret;
4791}
4792
4793static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304794 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304795 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304796{
Dino Myclee8843b32014-07-04 14:21:45 +05304797 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304798 struct net_device *dev = wdev->netdev;
4799 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4800 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4801 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4802 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304803 int retval;
4804 unsigned long rc;
4805 struct hdd_ext_scan_context *context;
4806 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304807
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304808 ENTER();
4809
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304810 if (VOS_FTM_MODE == hdd_get_conparam()) {
4811 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4812 return -EINVAL;
4813 }
4814
Dino Mycle6fb96c12014-06-10 11:52:40 +05304815 status = wlan_hdd_validate_context(pHddCtx);
4816 if (0 != status)
4817 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304818 return -EINVAL;
4819 }
Dino Myclee8843b32014-07-04 14:21:45 +05304820 /* check the EXTScan Capability */
4821 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304822 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4823 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304824 {
4825 hddLog(VOS_TRACE_LEVEL_ERROR,
4826 FL("EXTScan not enabled/supported by Firmware"));
4827 return -EINVAL;
4828 }
4829
Dino Mycle6fb96c12014-06-10 11:52:40 +05304830 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4831 data, dataLen,
4832 wlan_hdd_extscan_config_policy)) {
4833 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4834 return -EINVAL;
4835 }
4836
4837 /* Parse and fetch request Id */
4838 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4839 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4840 return -EINVAL;
4841 }
4842
Dino Myclee8843b32014-07-04 14:21:45 +05304843 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304844 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304845 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304846
Dino Myclee8843b32014-07-04 14:21:45 +05304847 reqMsg.sessionId = pAdapter->sessionId;
4848 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304849
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304850 context = &pHddCtx->ext_scan_context;
4851 spin_lock(&hdd_context_lock);
4852 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304853 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304854 spin_unlock(&hdd_context_lock);
4855
Dino Myclee8843b32014-07-04 14:21:45 +05304856 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304857 if (!HAL_STATUS_SUCCESS(status)) {
4858 hddLog(VOS_TRACE_LEVEL_ERROR,
4859 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304860 return -EINVAL;
4861 }
4862
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304863 /* request was sent -- wait for the response */
4864 rc = wait_for_completion_timeout(&context->response_event,
4865 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4866
4867 if (!rc) {
4868 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4869 retval = -ETIMEDOUT;
4870 } else {
4871 spin_lock(&hdd_context_lock);
4872 if (context->request_id == request_id)
4873 retval = context->response_status;
4874 else
4875 retval = -EINVAL;
4876 spin_unlock(&hdd_context_lock);
4877 }
4878
4879 return retval;
4880
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304881 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304882 return 0;
4883}
4884
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304885static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4886 struct wireless_dev *wdev,
4887 const void *data, int dataLen)
4888{
4889 int ret = 0;
4890
4891 vos_ssr_protect(__func__);
4892 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4893 vos_ssr_unprotect(__func__);
4894
4895 return ret;
4896}
4897
4898static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304899 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304900 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304901{
Dino Myclee8843b32014-07-04 14:21:45 +05304902 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304903 struct net_device *dev = wdev->netdev;
4904 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4905 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4906 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4907 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304908 struct hdd_ext_scan_context *context;
4909 tANI_U32 request_id;
4910 unsigned long rc;
4911 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304912
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304913 ENTER();
4914
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304915 if (VOS_FTM_MODE == hdd_get_conparam()) {
4916 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4917 return -EINVAL;
4918 }
4919
Dino Mycle6fb96c12014-06-10 11:52:40 +05304920 status = wlan_hdd_validate_context(pHddCtx);
4921 if (0 != status)
4922 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304923 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304924 return -EINVAL;
4925 }
Dino Myclee8843b32014-07-04 14:21:45 +05304926 /* check the EXTScan Capability */
4927 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304928 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4929 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304930 {
4931 hddLog(VOS_TRACE_LEVEL_ERROR,
4932 FL("EXTScan not enabled/supported by Firmware"));
4933 return -EINVAL;
4934 }
4935
Dino Mycle6fb96c12014-06-10 11:52:40 +05304936 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4937 data, dataLen,
4938 wlan_hdd_extscan_config_policy)) {
4939 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4940 return -EINVAL;
4941 }
4942
4943 /* Parse and fetch request Id */
4944 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4945 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4946 return -EINVAL;
4947 }
4948
Dino Myclee8843b32014-07-04 14:21:45 +05304949 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304950 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304951 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304952
Dino Myclee8843b32014-07-04 14:21:45 +05304953 reqMsg.sessionId = pAdapter->sessionId;
4954 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304955
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304956 context = &pHddCtx->ext_scan_context;
4957 spin_lock(&hdd_context_lock);
4958 INIT_COMPLETION(context->response_event);
4959 context->request_id = request_id = reqMsg.requestId;
4960 spin_unlock(&hdd_context_lock);
4961
Dino Myclee8843b32014-07-04 14:21:45 +05304962 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304963 if (!HAL_STATUS_SUCCESS(status)) {
4964 hddLog(VOS_TRACE_LEVEL_ERROR,
4965 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304966 return -EINVAL;
4967 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304968
4969 /* request was sent -- wait for the response */
4970 rc = wait_for_completion_timeout(&context->response_event,
4971 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4972 if (!rc) {
4973 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4974 retval = -ETIMEDOUT;
4975 } else {
4976 spin_lock(&hdd_context_lock);
4977 if (context->request_id == request_id)
4978 retval = context->response_status;
4979 else
4980 retval = -EINVAL;
4981 spin_unlock(&hdd_context_lock);
4982 }
4983
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304984 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304985 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304986}
4987
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304988static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4989 struct wireless_dev *wdev,
4990 const void *data, int dataLen)
4991{
4992 int ret = 0;
4993
4994 vos_ssr_protect(__func__);
4995 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4996 vos_ssr_unprotect(__func__);
4997
4998 return ret;
4999}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305000#endif /* WLAN_FEATURE_EXTSCAN */
5001
Atul Mittal115287b2014-07-08 13:26:33 +05305002/*EXT TDLS*/
5003static const struct nla_policy
5004wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5005{
5006 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5007 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5008 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5009 {.type = NLA_S32 },
5010 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5011 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5012
5013};
5014
5015static const struct nla_policy
5016wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5017{
5018 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5019
5020};
5021
5022static const struct nla_policy
5023wlan_hdd_tdls_config_state_change_policy[
5024 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5025{
5026 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
5027 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5028 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305029 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5030 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5031 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305032
5033};
5034
5035static const struct nla_policy
5036wlan_hdd_tdls_config_get_status_policy[
5037 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5038{
5039 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5040 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5041 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305042 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5043 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5044 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305045
5046};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305047
5048static const struct nla_policy
5049wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5050{
5051 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5052};
5053
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305054static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305055 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305056 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305057 int data_len)
5058{
5059
5060 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5061 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5062
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305063 ENTER();
5064
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305065 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305066 return -EINVAL;
5067 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305068 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305069 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305070 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305071 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305072 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305073 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305074 return -ENOTSUPP;
5075 }
5076
5077 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5078 data, data_len, wlan_hdd_mac_config)) {
5079 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5080 return -EINVAL;
5081 }
5082
5083 /* Parse and fetch mac address */
5084 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5086 return -EINVAL;
5087 }
5088
5089 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5090 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5091 VOS_MAC_ADDR_LAST_3_BYTES);
5092
Siddharth Bhal76972212014-10-15 16:22:51 +05305093 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5094
5095 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305096 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5097 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305098 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5099 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5100 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5101 {
5102 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5103 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5104 VOS_MAC_ADDRESS_LEN);
5105 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305106 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305107
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305108 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5109 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305110
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305111 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305112 return 0;
5113}
5114
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305115static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5116 struct wireless_dev *wdev,
5117 const void *data,
5118 int data_len)
5119{
5120 int ret = 0;
5121
5122 vos_ssr_protect(__func__);
5123 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5124 vos_ssr_unprotect(__func__);
5125
5126 return ret;
5127}
5128
5129static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305130 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305131 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305132 int data_len)
5133{
5134 u8 peer[6] = {0};
5135 struct net_device *dev = wdev->netdev;
5136 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5137 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5138 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5139 eHalStatus ret;
5140 tANI_S32 state;
5141 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305142 tANI_S32 global_operating_class = 0;
5143 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305144 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305145 int retVal;
5146
5147 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305148
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305149 if (!pAdapter) {
5150 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5151 return -EINVAL;
5152 }
5153
Atul Mittal115287b2014-07-08 13:26:33 +05305154 ret = wlan_hdd_validate_context(pHddCtx);
5155 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305156 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305157 return -EINVAL;
5158 }
5159 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305161 return -ENOTSUPP;
5162 }
5163 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5164 data, data_len,
5165 wlan_hdd_tdls_config_get_status_policy)) {
5166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5167 return -EINVAL;
5168 }
5169
5170 /* Parse and fetch mac address */
5171 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5172 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5173 return -EINVAL;
5174 }
5175
5176 memcpy(peer, nla_data(
5177 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5178 sizeof(peer));
5179 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5180
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305181 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305182
Atul Mittal115287b2014-07-08 13:26:33 +05305183 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305184 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305185 NLMSG_HDRLEN);
5186
5187 if (!skb) {
5188 hddLog(VOS_TRACE_LEVEL_ERROR,
5189 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5190 return -EINVAL;
5191 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305192 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 +05305193 reason,
5194 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305195 global_operating_class,
5196 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305197 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305198 if (nla_put_s32(skb,
5199 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5200 state) ||
5201 nla_put_s32(skb,
5202 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5203 reason) ||
5204 nla_put_s32(skb,
5205 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5206 global_operating_class) ||
5207 nla_put_s32(skb,
5208 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5209 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305210
5211 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5212 goto nla_put_failure;
5213 }
5214
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305215 retVal = cfg80211_vendor_cmd_reply(skb);
5216 EXIT();
5217 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305218
5219nla_put_failure:
5220 kfree_skb(skb);
5221 return -EINVAL;
5222}
5223
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305224static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5225 struct wireless_dev *wdev,
5226 const void *data,
5227 int data_len)
5228{
5229 int ret = 0;
5230
5231 vos_ssr_protect(__func__);
5232 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5233 vos_ssr_unprotect(__func__);
5234
5235 return ret;
5236}
5237
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305238static int wlan_hdd_cfg80211_exttdls_callback(
5239#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5240 const tANI_U8* mac,
5241#else
5242 tANI_U8* mac,
5243#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305244 tANI_S32 state,
5245 tANI_S32 reason,
5246 void *ctx)
5247{
5248 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305249 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305250 tANI_S32 global_operating_class = 0;
5251 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305252 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305253
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305254 ENTER();
5255
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305256 if (!pAdapter) {
5257 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5258 return -EINVAL;
5259 }
5260
5261 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305262 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305263 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305264 return -EINVAL;
5265 }
5266
5267 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305268 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305269 return -ENOTSUPP;
5270 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305271 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5272#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5273 NULL,
5274#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305275 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5276 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5277 GFP_KERNEL);
5278
5279 if (!skb) {
5280 hddLog(VOS_TRACE_LEVEL_ERROR,
5281 FL("cfg80211_vendor_event_alloc failed"));
5282 return -EINVAL;
5283 }
5284 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305285 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5286 reason,
5287 state,
5288 global_operating_class,
5289 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305290 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5291 MAC_ADDR_ARRAY(mac));
5292
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305293 if (nla_put(skb,
5294 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5295 VOS_MAC_ADDR_SIZE, mac) ||
5296 nla_put_s32(skb,
5297 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5298 state) ||
5299 nla_put_s32(skb,
5300 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5301 reason) ||
5302 nla_put_s32(skb,
5303 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5304 channel) ||
5305 nla_put_s32(skb,
5306 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5307 global_operating_class)
5308 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305309 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5310 goto nla_put_failure;
5311 }
5312
5313 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305314 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305315 return (0);
5316
5317nla_put_failure:
5318 kfree_skb(skb);
5319 return -EINVAL;
5320}
5321
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305322static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305323 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305324 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305325 int data_len)
5326{
5327 u8 peer[6] = {0};
5328 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305329 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5330 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5331 eHalStatus status;
5332 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305333 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305334 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305335
5336 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305337
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305338 if (!dev) {
5339 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5340 return -EINVAL;
5341 }
5342
5343 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5344 if (!pAdapter) {
5345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5346 return -EINVAL;
5347 }
5348
Atul Mittal115287b2014-07-08 13:26:33 +05305349 status = wlan_hdd_validate_context(pHddCtx);
5350 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305352 return -EINVAL;
5353 }
5354 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305356 return -ENOTSUPP;
5357 }
5358 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5359 data, data_len,
5360 wlan_hdd_tdls_config_enable_policy)) {
5361 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5362 return -EINVAL;
5363 }
5364
5365 /* Parse and fetch mac address */
5366 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5367 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5368 return -EINVAL;
5369 }
5370
5371 memcpy(peer, nla_data(
5372 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5373 sizeof(peer));
5374 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5375
5376 /* Parse and fetch channel */
5377 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5378 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5379 return -EINVAL;
5380 }
5381 pReqMsg.channel = nla_get_s32(
5382 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5383 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5384
5385 /* Parse and fetch global operating class */
5386 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5387 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5388 return -EINVAL;
5389 }
5390 pReqMsg.global_operating_class = nla_get_s32(
5391 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5392 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5393 pReqMsg.global_operating_class);
5394
5395 /* Parse and fetch latency ms */
5396 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5397 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5398 return -EINVAL;
5399 }
5400 pReqMsg.max_latency_ms = nla_get_s32(
5401 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5402 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5403 pReqMsg.max_latency_ms);
5404
5405 /* Parse and fetch required bandwidth kbps */
5406 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5407 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5408 return -EINVAL;
5409 }
5410
5411 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5412 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5413 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5414 pReqMsg.min_bandwidth_kbps);
5415
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305416 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305417 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305418 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305419 wlan_hdd_cfg80211_exttdls_callback);
5420
5421 EXIT();
5422 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305423}
5424
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305425static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5426 struct wireless_dev *wdev,
5427 const void *data,
5428 int data_len)
5429{
5430 int ret = 0;
5431
5432 vos_ssr_protect(__func__);
5433 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5434 vos_ssr_unprotect(__func__);
5435
5436 return ret;
5437}
5438
5439static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305440 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305441 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305442 int data_len)
5443{
5444 u8 peer[6] = {0};
5445 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305446 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5447 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5448 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305449 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305450 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305451
5452 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305453
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305454 if (!dev) {
5455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5456 return -EINVAL;
5457 }
5458
5459 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5460 if (!pAdapter) {
5461 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5462 return -EINVAL;
5463 }
5464
Atul Mittal115287b2014-07-08 13:26:33 +05305465 status = wlan_hdd_validate_context(pHddCtx);
5466 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305467 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305468 return -EINVAL;
5469 }
5470 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305472 return -ENOTSUPP;
5473 }
5474 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5475 data, data_len,
5476 wlan_hdd_tdls_config_disable_policy)) {
5477 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5478 return -EINVAL;
5479 }
5480 /* Parse and fetch mac address */
5481 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5482 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5483 return -EINVAL;
5484 }
5485
5486 memcpy(peer, nla_data(
5487 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5488 sizeof(peer));
5489 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5490
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305491 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5492
5493 EXIT();
5494 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305495}
5496
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305497static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5498 struct wireless_dev *wdev,
5499 const void *data,
5500 int data_len)
5501{
5502 int ret = 0;
5503
5504 vos_ssr_protect(__func__);
5505 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5506 vos_ssr_unprotect(__func__);
5507
5508 return ret;
5509}
5510
Dasari Srinivas7875a302014-09-26 17:50:57 +05305511static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305512__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305513 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305514 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305515{
5516 struct net_device *dev = wdev->netdev;
5517 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5518 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5519 struct sk_buff *skb = NULL;
5520 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305521 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305522
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305523 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305524
5525 ret = wlan_hdd_validate_context(pHddCtx);
5526 if (0 != ret)
5527 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305528 return ret;
5529 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305530 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5531 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5532 fset |= WIFI_FEATURE_INFRA;
5533 }
5534
5535 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5536 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5537 fset |= WIFI_FEATURE_INFRA_5G;
5538 }
5539
5540#ifdef WLAN_FEATURE_P2P
5541 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5542 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5543 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5544 fset |= WIFI_FEATURE_P2P;
5545 }
5546#endif
5547
5548 /* Soft-AP is supported currently by default */
5549 fset |= WIFI_FEATURE_SOFT_AP;
5550
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305551 /* HOTSPOT is a supplicant feature, enable it by default */
5552 fset |= WIFI_FEATURE_HOTSPOT;
5553
Dasari Srinivas7875a302014-09-26 17:50:57 +05305554#ifdef WLAN_FEATURE_EXTSCAN
5555 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305556 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5557 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5558 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305559 fset |= WIFI_FEATURE_EXTSCAN;
5560 }
5561#endif
5562
Dasari Srinivas7875a302014-09-26 17:50:57 +05305563 if (sme_IsFeatureSupportedByFW(NAN)) {
5564 hddLog(LOG1, FL("NAN is supported by firmware"));
5565 fset |= WIFI_FEATURE_NAN;
5566 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305567
5568 /* D2D RTT is not supported currently by default */
5569 if (sme_IsFeatureSupportedByFW(RTT)) {
5570 hddLog(LOG1, FL("RTT is supported by firmware"));
5571 fset |= WIFI_FEATURE_D2AP_RTT;
5572 }
5573
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305574 if (sme_IsFeatureSupportedByFW(RTT3)) {
5575 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5576 fset |= WIFI_FEATURE_RTT3;
5577 }
5578
Dasari Srinivas7875a302014-09-26 17:50:57 +05305579#ifdef FEATURE_WLAN_BATCH_SCAN
5580 if (fset & WIFI_FEATURE_EXTSCAN) {
5581 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5582 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5583 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5584 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5585 fset |= WIFI_FEATURE_BATCH_SCAN;
5586 }
5587#endif
5588
5589#ifdef FEATURE_WLAN_SCAN_PNO
5590 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5591 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5592 hddLog(LOG1, FL("PNO is supported by firmware"));
5593 fset |= WIFI_FEATURE_PNO;
5594 }
5595#endif
5596
5597 /* STA+STA is supported currently by default */
5598 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5599
5600#ifdef FEATURE_WLAN_TDLS
5601 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5602 sme_IsFeatureSupportedByFW(TDLS)) {
5603 hddLog(LOG1, FL("TDLS is supported by firmware"));
5604 fset |= WIFI_FEATURE_TDLS;
5605 }
5606
5607 /* TDLS_OFFCHANNEL is not supported currently by default */
5608#endif
5609
5610#ifdef WLAN_AP_STA_CONCURRENCY
5611 /* AP+STA concurrency is supported currently by default */
5612 fset |= WIFI_FEATURE_AP_STA;
5613#endif
5614
Mukul Sharma5add0532015-08-17 15:57:47 +05305615#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5616 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5617 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5618#endif
5619
Dasari Srinivas7875a302014-09-26 17:50:57 +05305620 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5621 NLMSG_HDRLEN);
5622
5623 if (!skb) {
5624 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5625 return -EINVAL;
5626 }
5627 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5628
5629 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5630 hddLog(LOGE, FL("nla put fail"));
5631 goto nla_put_failure;
5632 }
5633
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305634 ret = cfg80211_vendor_cmd_reply(skb);
5635 EXIT();
5636 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305637
5638nla_put_failure:
5639 kfree_skb(skb);
5640 return -EINVAL;
5641}
5642
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305643static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305644wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5645 struct wireless_dev *wdev,
5646 const void *data, int data_len)
5647{
5648 int ret = 0;
5649
5650 vos_ssr_protect(__func__);
5651 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5652 vos_ssr_unprotect(__func__);
5653
5654 return ret;
5655}
5656
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305657
5658static const struct
5659nla_policy
5660qca_wlan_vendor_wifi_logger_get_ring_data_policy
5661[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5662 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5663 = {.type = NLA_U32 },
5664};
5665
5666static int
5667 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5668 struct wireless_dev *wdev,
5669 const void *data,
5670 int data_len)
5671{
5672 int ret;
5673 VOS_STATUS status;
5674 uint32_t ring_id;
5675 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5676 struct nlattr *tb
5677 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5678
5679 ENTER();
5680
5681 ret = wlan_hdd_validate_context(hdd_ctx);
5682 if (0 != ret) {
5683 return ret;
5684 }
5685
5686 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5687 data, data_len,
5688 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5689 hddLog(LOGE, FL("Invalid attribute"));
5690 return -EINVAL;
5691 }
5692
5693 /* Parse and fetch ring id */
5694 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5695 hddLog(LOGE, FL("attr ATTR failed"));
5696 return -EINVAL;
5697 }
5698
5699 ring_id = nla_get_u32(
5700 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5701
5702 hddLog(LOG1, FL("Bug report triggered by framework"));
5703
5704 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5705 WLAN_LOG_INDICATOR_FRAMEWORK,
5706 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305707 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305708 );
5709 if (VOS_STATUS_SUCCESS != status) {
5710 hddLog(LOGE, FL("Failed to trigger bug report"));
5711
5712 return -EINVAL;
5713 }
5714
5715 return 0;
5716
5717
5718}
5719
5720
5721static int
5722 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5723 struct wireless_dev *wdev,
5724 const void *data,
5725 int data_len)
5726{
5727 int ret = 0;
5728
5729 vos_ssr_protect(__func__);
5730 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5731 wdev, data, data_len);
5732 vos_ssr_unprotect(__func__);
5733
5734 return ret;
5735
5736}
5737
5738
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305739static int
5740__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305741 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305742 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305743{
5744 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5745 uint8_t i, feature_sets, max_feature_sets;
5746 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5747 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305748 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5749 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305750
5751 ENTER();
5752
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305753 ret = wlan_hdd_validate_context(pHddCtx);
5754 if (0 != ret)
5755 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305756 return ret;
5757 }
5758
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305759 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5760 data, data_len, NULL)) {
5761 hddLog(LOGE, FL("Invalid ATTR"));
5762 return -EINVAL;
5763 }
5764
5765 /* Parse and fetch max feature set */
5766 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5767 hddLog(LOGE, FL("Attr max feature set size failed"));
5768 return -EINVAL;
5769 }
5770 max_feature_sets = nla_get_u32(
5771 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5772 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5773
5774 /* Fill feature combination matrix */
5775 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305776 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5777 WIFI_FEATURE_P2P;
5778
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305779 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5780 WIFI_FEATURE_SOFT_AP;
5781
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305782 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5783 WIFI_FEATURE_SOFT_AP;
5784
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305785 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5786 WIFI_FEATURE_SOFT_AP |
5787 WIFI_FEATURE_P2P;
5788
5789 /* Add more feature combinations here */
5790
5791 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5792 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5793 hddLog(LOG1, "Feature set matrix");
5794 for (i = 0; i < feature_sets; i++)
5795 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5796
5797 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5798 sizeof(u32) * feature_sets +
5799 NLMSG_HDRLEN);
5800
5801 if (reply_skb) {
5802 if (nla_put_u32(reply_skb,
5803 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5804 feature_sets) ||
5805 nla_put(reply_skb,
5806 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5807 sizeof(u32) * feature_sets, feature_set_matrix)) {
5808 hddLog(LOGE, FL("nla put fail"));
5809 kfree_skb(reply_skb);
5810 return -EINVAL;
5811 }
5812
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305813 ret = cfg80211_vendor_cmd_reply(reply_skb);
5814 EXIT();
5815 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305816 }
5817 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5818 return -ENOMEM;
5819
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305820}
5821
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305822static int
5823wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5824 struct wireless_dev *wdev,
5825 const void *data, int data_len)
5826{
5827 int ret = 0;
5828
5829 vos_ssr_protect(__func__);
5830 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5831 data_len);
5832 vos_ssr_unprotect(__func__);
5833
5834 return ret;
5835}
5836
c_manjeecfd1efb2015-09-25 19:32:34 +05305837
5838static int
5839__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5840 struct wireless_dev *wdev,
5841 const void *data, int data_len)
5842{
5843 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5844 int ret;
5845 ENTER();
5846
5847 ret = wlan_hdd_validate_context(pHddCtx);
5848 if (0 != ret)
5849 {
5850 return ret;
5851 }
5852
5853 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5854 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5855 {
5856 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5857 return -EINVAL;
5858 }
5859 /*call common API for FW mem dump req*/
5860 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5861
Abhishek Singhc783fa72015-12-09 18:07:34 +05305862 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305863 {
5864 /*indicate to userspace the status of fw mem dump */
5865 wlan_indicate_mem_dump_complete(true);
5866 }
5867 else
5868 {
5869 /*else send failure to userspace */
5870 wlan_indicate_mem_dump_complete(false);
5871 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305872 EXIT();
5873 return ret;
5874}
5875
5876/**
5877 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5878 * @wiphy: pointer to wireless wiphy structure.
5879 * @wdev: pointer to wireless_dev structure.
5880 * @data: Pointer to the NL data.
5881 * @data_len:Length of @data
5882 *
5883 * This is called when wlan driver needs to get the firmware memory dump
5884 * via vendor specific command.
5885 *
5886 * Return: 0 on success, error number otherwise.
5887 */
5888
5889static int
5890wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5891 struct wireless_dev *wdev,
5892 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305893{
5894 int ret = 0;
5895 vos_ssr_protect(__func__);
5896 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5897 data_len);
5898 vos_ssr_unprotect(__func__);
5899 return ret;
5900}
c_manjeecfd1efb2015-09-25 19:32:34 +05305901
Sushant Kaushik8e644982015-09-23 12:18:54 +05305902static const struct
5903nla_policy
5904qca_wlan_vendor_wifi_logger_start_policy
5905[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5906 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5907 = {.type = NLA_U32 },
5908 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5909 = {.type = NLA_U32 },
5910 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5911 = {.type = NLA_U32 },
5912};
5913
5914/**
5915 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5916 * or disable the collection of packet statistics from the firmware
5917 * @wiphy: WIPHY structure pointer
5918 * @wdev: Wireless device structure pointer
5919 * @data: Pointer to the data received
5920 * @data_len: Length of the data received
5921 *
5922 * This function is used to enable or disable the collection of packet
5923 * statistics from the firmware
5924 *
5925 * Return: 0 on success and errno on failure
5926 */
5927static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5928 struct wireless_dev *wdev,
5929 const void *data,
5930 int data_len)
5931{
5932 eHalStatus status;
5933 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5934 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5935 tAniWifiStartLog start_log;
5936
5937 status = wlan_hdd_validate_context(hdd_ctx);
5938 if (0 != status) {
5939 return -EINVAL;
5940 }
5941
5942 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5943 data, data_len,
5944 qca_wlan_vendor_wifi_logger_start_policy)) {
5945 hddLog(LOGE, FL("Invalid attribute"));
5946 return -EINVAL;
5947 }
5948
5949 /* Parse and fetch ring id */
5950 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5951 hddLog(LOGE, FL("attr ATTR failed"));
5952 return -EINVAL;
5953 }
5954 start_log.ringId = nla_get_u32(
5955 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5956 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5957
5958 /* Parse and fetch verbose level */
5959 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5960 hddLog(LOGE, FL("attr verbose_level failed"));
5961 return -EINVAL;
5962 }
5963 start_log.verboseLevel = nla_get_u32(
5964 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5965 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5966
5967 /* Parse and fetch flag */
5968 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5969 hddLog(LOGE, FL("attr flag failed"));
5970 return -EINVAL;
5971 }
5972 start_log.flag = nla_get_u32(
5973 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5974 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5975
5976 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305977 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5978 !vos_isPktStatsEnabled()))
5979
Sushant Kaushik8e644982015-09-23 12:18:54 +05305980 {
5981 hddLog(LOGE, FL("per pkt stats not enabled"));
5982 return -EINVAL;
5983 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305984
Sushant Kaushik33200572015-08-05 16:46:20 +05305985 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305986 return 0;
5987}
5988
5989/**
5990 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5991 * or disable the collection of packet statistics from the firmware
5992 * @wiphy: WIPHY structure pointer
5993 * @wdev: Wireless device structure pointer
5994 * @data: Pointer to the data received
5995 * @data_len: Length of the data received
5996 *
5997 * This function is used to enable or disable the collection of packet
5998 * statistics from the firmware
5999 *
6000 * Return: 0 on success and errno on failure
6001 */
6002static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6003 struct wireless_dev *wdev,
6004 const void *data,
6005 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306006{
6007 int ret = 0;
6008
6009 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306010
6011 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6012 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306013 vos_ssr_unprotect(__func__);
6014
6015 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306016}
6017
6018
Agarwal Ashish738843c2014-09-25 12:27:56 +05306019static const struct nla_policy
6020wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6021 +1] =
6022{
6023 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6024};
6025
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306026static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306027 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306028 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306029 int data_len)
6030{
6031 struct net_device *dev = wdev->netdev;
6032 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6033 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6034 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6035 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6036 eHalStatus status;
6037 u32 dfsFlag = 0;
6038
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306039 ENTER();
6040
Agarwal Ashish738843c2014-09-25 12:27:56 +05306041 status = wlan_hdd_validate_context(pHddCtx);
6042 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306043 return -EINVAL;
6044 }
6045 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6046 data, data_len,
6047 wlan_hdd_set_no_dfs_flag_config_policy)) {
6048 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6049 return -EINVAL;
6050 }
6051
6052 /* Parse and fetch required bandwidth kbps */
6053 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6055 return -EINVAL;
6056 }
6057
6058 dfsFlag = nla_get_u32(
6059 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6060 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6061 dfsFlag);
6062
6063 pHddCtx->disable_dfs_flag = dfsFlag;
6064
6065 sme_disable_dfs_channel(hHal, dfsFlag);
6066 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306067
6068 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306069 return 0;
6070}
Atul Mittal115287b2014-07-08 13:26:33 +05306071
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306072static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6073 struct wireless_dev *wdev,
6074 const void *data,
6075 int data_len)
6076{
6077 int ret = 0;
6078
6079 vos_ssr_protect(__func__);
6080 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6081 vos_ssr_unprotect(__func__);
6082
6083 return ret;
6084
6085}
6086
Mukul Sharma2a271632014-10-13 14:59:01 +05306087const struct
6088nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6089{
6090 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6091 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6092};
6093
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306094static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306095 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306096{
6097
6098 u8 bssid[6] = {0};
6099 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6100 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6101 eHalStatus status = eHAL_STATUS_SUCCESS;
6102 v_U32_t isFwrRoamEnabled = FALSE;
6103 int ret;
6104
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306105 ENTER();
6106
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306107 ret = wlan_hdd_validate_context(pHddCtx);
6108 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306109 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306110 }
6111
6112 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6113 data, data_len,
6114 qca_wlan_vendor_attr);
6115 if (ret){
6116 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6117 return -EINVAL;
6118 }
6119
6120 /* Parse and fetch Enable flag */
6121 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6122 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6123 return -EINVAL;
6124 }
6125
6126 isFwrRoamEnabled = nla_get_u32(
6127 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6128
6129 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6130
6131 /* Parse and fetch bssid */
6132 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6133 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6134 return -EINVAL;
6135 }
6136
6137 memcpy(bssid, nla_data(
6138 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6139 sizeof(bssid));
6140 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6141
6142 //Update roaming
6143 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306144 if (!HAL_STATUS_SUCCESS(status)) {
6145 hddLog(LOGE,
6146 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6147 return -EINVAL;
6148 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306149 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306150 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306151}
6152
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306153static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6154 struct wireless_dev *wdev, const void *data, int data_len)
6155{
6156 int ret = 0;
6157
6158 vos_ssr_protect(__func__);
6159 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6160 vos_ssr_unprotect(__func__);
6161
6162 return ret;
6163}
6164
Sushant Kaushik847890c2015-09-28 16:05:17 +05306165static const struct
6166nla_policy
6167qca_wlan_vendor_get_wifi_info_policy[
6168 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6169 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6170 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6171};
6172
6173
6174/**
6175 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6176 * @wiphy: pointer to wireless wiphy structure.
6177 * @wdev: pointer to wireless_dev structure.
6178 * @data: Pointer to the data to be passed via vendor interface
6179 * @data_len:Length of the data to be passed
6180 *
6181 * This is called when wlan driver needs to send wifi driver related info
6182 * (driver/fw version) to the user space application upon request.
6183 *
6184 * Return: Return the Success or Failure code.
6185 */
6186static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6187 struct wireless_dev *wdev,
6188 const void *data, int data_len)
6189{
6190 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6191 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6192 tSirVersionString version;
6193 uint32 version_len;
6194 uint8 attr;
6195 int status;
6196 struct sk_buff *reply_skb = NULL;
6197
6198 if (VOS_FTM_MODE == hdd_get_conparam()) {
6199 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6200 return -EINVAL;
6201 }
6202
6203 status = wlan_hdd_validate_context(hdd_ctx);
6204 if (0 != status) {
6205 hddLog(LOGE, FL("HDD context is not valid"));
6206 return -EINVAL;
6207 }
6208
6209 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6210 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6211 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6212 return -EINVAL;
6213 }
6214
6215 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6216 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6217 QWLAN_VERSIONSTR);
6218 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6219 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6220 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6221 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6222 hdd_ctx->fw_Version);
6223 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6224 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6225 } else {
6226 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6227 return -EINVAL;
6228 }
6229
6230 version_len = strlen(version);
6231 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6232 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6233 if (!reply_skb) {
6234 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6235 return -ENOMEM;
6236 }
6237
6238 if (nla_put(reply_skb, attr, version_len, version)) {
6239 hddLog(LOGE, FL("nla put fail"));
6240 kfree_skb(reply_skb);
6241 return -EINVAL;
6242 }
6243
6244 return cfg80211_vendor_cmd_reply(reply_skb);
6245}
6246
6247/**
6248 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6249 * @wiphy: pointer to wireless wiphy structure.
6250 * @wdev: pointer to wireless_dev structure.
6251 * @data: Pointer to the data to be passed via vendor interface
6252 * @data_len:Length of the data to be passed
6253 * @data_len: Length of the data received
6254 *
6255 * This function is used to enable or disable the collection of packet
6256 * statistics from the firmware
6257 *
6258 * Return: 0 on success and errno on failure
6259 */
6260
6261static int
6262wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6263 struct wireless_dev *wdev,
6264 const void *data, int data_len)
6265
6266
6267{
6268 int ret = 0;
6269
6270 vos_ssr_protect(__func__);
6271 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6272 wdev, data, data_len);
6273 vos_ssr_unprotect(__func__);
6274
6275 return ret;
6276}
6277
6278
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306279/*
6280 * define short names for the global vendor params
6281 * used by __wlan_hdd_cfg80211_monitor_rssi()
6282 */
6283#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6284#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6285#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6286#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6287#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6288
6289/**---------------------------------------------------------------------------
6290
6291 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6292 monitor start is completed successfully.
6293
6294 \return - None
6295
6296 --------------------------------------------------------------------------*/
6297void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6298{
6299 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6300
6301 if (NULL == pHddCtx)
6302 {
6303 hddLog(VOS_TRACE_LEVEL_ERROR,
6304 "%s: HDD context is NULL",__func__);
6305 return;
6306 }
6307
6308 if (VOS_STATUS_SUCCESS == status)
6309 {
6310 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6311 }
6312 else
6313 {
6314 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6315 }
6316
6317 return;
6318}
6319
6320/**---------------------------------------------------------------------------
6321
6322 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6323 stop is completed successfully.
6324
6325 \return - None
6326
6327 --------------------------------------------------------------------------*/
6328void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6329{
6330 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6331
6332 if (NULL == pHddCtx)
6333 {
6334 hddLog(VOS_TRACE_LEVEL_ERROR,
6335 "%s: HDD context is NULL",__func__);
6336 return;
6337 }
6338
6339 if (VOS_STATUS_SUCCESS == status)
6340 {
6341 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6342 }
6343 else
6344 {
6345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6346 }
6347
6348 return;
6349}
6350
6351/**
6352 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6353 * @wiphy: Pointer to wireless phy
6354 * @wdev: Pointer to wireless device
6355 * @data: Pointer to data
6356 * @data_len: Data length
6357 *
6358 * Return: 0 on success, negative errno on failure
6359 */
6360
6361static int
6362__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6363 struct wireless_dev *wdev,
6364 const void *data,
6365 int data_len)
6366{
6367 struct net_device *dev = wdev->netdev;
6368 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6369 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6370 hdd_station_ctx_t *pHddStaCtx;
6371 struct nlattr *tb[PARAM_MAX + 1];
6372 tpSirRssiMonitorReq pReq;
6373 eHalStatus status;
6374 int ret;
6375 uint32_t control;
6376 static const struct nla_policy policy[PARAM_MAX + 1] = {
6377 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6378 [PARAM_CONTROL] = { .type = NLA_U32 },
6379 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6380 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6381 };
6382
6383 ENTER();
6384
6385 ret = wlan_hdd_validate_context(hdd_ctx);
6386 if (0 != ret) {
6387 return -EINVAL;
6388 }
6389
6390 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6391 hddLog(LOGE, FL("Not in Connected state!"));
6392 return -ENOTSUPP;
6393 }
6394
6395 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6396 hddLog(LOGE, FL("Invalid ATTR"));
6397 return -EINVAL;
6398 }
6399
6400 if (!tb[PARAM_REQUEST_ID]) {
6401 hddLog(LOGE, FL("attr request id failed"));
6402 return -EINVAL;
6403 }
6404
6405 if (!tb[PARAM_CONTROL]) {
6406 hddLog(LOGE, FL("attr control failed"));
6407 return -EINVAL;
6408 }
6409
6410 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6411
6412 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6413 if(NULL == pReq)
6414 {
6415 hddLog(LOGE,
6416 FL("vos_mem_alloc failed "));
6417 return eHAL_STATUS_FAILED_ALLOC;
6418 }
6419 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6420
6421 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6422 pReq->sessionId = pAdapter->sessionId;
6423 pReq->rssiMonitorCbContext = hdd_ctx;
6424 control = nla_get_u32(tb[PARAM_CONTROL]);
6425 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6426
6427 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6428 pReq->requestId, pReq->sessionId, control);
6429
6430 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6431 if (!tb[PARAM_MIN_RSSI]) {
6432 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306433 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306434 }
6435
6436 if (!tb[PARAM_MAX_RSSI]) {
6437 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306438 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306439 }
6440
6441 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6442 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6443 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6444
6445 if (!(pReq->minRssi < pReq->maxRssi)) {
6446 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6447 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306448 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306449 }
6450 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6451 pReq->minRssi, pReq->maxRssi);
6452 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6453
6454 }
6455 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6456 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6457 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6458 }
6459 else {
6460 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306461 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306462 }
6463
6464 if (!HAL_STATUS_SUCCESS(status)) {
6465 hddLog(LOGE,
6466 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306467 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306468 }
6469
6470 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306471fail:
6472 vos_mem_free(pReq);
6473 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306474}
6475
6476/*
6477 * done with short names for the global vendor params
6478 * used by __wlan_hdd_cfg80211_monitor_rssi()
6479 */
6480#undef PARAM_MAX
6481#undef PARAM_CONTROL
6482#undef PARAM_REQUEST_ID
6483#undef PARAM_MAX_RSSI
6484#undef PARAM_MIN_RSSI
6485
6486/**
6487 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6488 * @wiphy: wiphy structure pointer
6489 * @wdev: Wireless device structure pointer
6490 * @data: Pointer to the data received
6491 * @data_len: Length of @data
6492 *
6493 * Return: 0 on success; errno on failure
6494 */
6495static int
6496wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6497 const void *data, int data_len)
6498{
6499 int ret;
6500
6501 vos_ssr_protect(__func__);
6502 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6503 vos_ssr_unprotect(__func__);
6504
6505 return ret;
6506}
6507
6508/**
6509 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6510 * @hddctx: HDD context
6511 * @data: rssi breached event data
6512 *
6513 * This function reads the rssi breached event %data and fill in the skb with
6514 * NL attributes and send up the NL event.
6515 * This callback execute in atomic context and must not invoke any
6516 * blocking calls.
6517 *
6518 * Return: none
6519 */
6520void hdd_rssi_threshold_breached_cb(void *hddctx,
6521 struct rssi_breach_event *data)
6522{
6523 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6524 int status;
6525 struct sk_buff *skb;
6526
6527 ENTER();
6528 status = wlan_hdd_validate_context(pHddCtx);
6529
6530 if (0 != status) {
6531 return;
6532 }
6533
6534 if (!data) {
6535 hddLog(LOGE, FL("data is null"));
6536 return;
6537 }
6538
6539 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6540#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6541 NULL,
6542#endif
6543 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6544 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6545 GFP_KERNEL);
6546
6547 if (!skb) {
6548 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6549 return;
6550 }
6551
6552 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6553 data->request_id, data->curr_rssi);
6554 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6555 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6556
6557 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6558 data->request_id) ||
6559 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6560 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6561 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6562 data->curr_rssi)) {
6563 hddLog(LOGE, FL("nla put fail"));
6564 goto fail;
6565 }
6566
6567 cfg80211_vendor_event(skb, GFP_KERNEL);
6568 return;
6569
6570fail:
6571 kfree_skb(skb);
6572 return;
6573}
6574
6575
6576
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306577/**
6578 * __wlan_hdd_cfg80211_setband() - set band
6579 * @wiphy: Pointer to wireless phy
6580 * @wdev: Pointer to wireless device
6581 * @data: Pointer to data
6582 * @data_len: Data length
6583 *
6584 * Return: 0 on success, negative errno on failure
6585 */
6586static int
6587__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6588 struct wireless_dev *wdev,
6589 const void *data,
6590 int data_len)
6591{
6592 struct net_device *dev = wdev->netdev;
6593 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6594 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6595 int ret;
6596 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6597 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6598
6599 ENTER();
6600
6601 ret = wlan_hdd_validate_context(hdd_ctx);
6602 if (0 != ret) {
6603 hddLog(LOGE, FL("HDD context is not valid"));
6604 return ret;
6605 }
6606
6607 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6608 policy)) {
6609 hddLog(LOGE, FL("Invalid ATTR"));
6610 return -EINVAL;
6611 }
6612
6613 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6614 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6615 return -EINVAL;
6616 }
6617
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306618 hdd_ctx->isSetBandByNL = TRUE;
6619 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306620 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306621 hdd_ctx->isSetBandByNL = FALSE;
6622
6623 EXIT();
6624 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306625}
6626
6627/**
6628 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6629 * @wiphy: wiphy structure pointer
6630 * @wdev: Wireless device structure pointer
6631 * @data: Pointer to the data received
6632 * @data_len: Length of @data
6633 *
6634 * Return: 0 on success; errno on failure
6635 */
6636static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6637 struct wireless_dev *wdev,
6638 const void *data,
6639 int data_len)
6640{
6641 int ret = 0;
6642
6643 vos_ssr_protect(__func__);
6644 ret = __wlan_hdd_cfg80211_setband(wiphy,
6645 wdev, data, data_len);
6646 vos_ssr_unprotect(__func__);
6647
6648 return ret;
6649}
6650
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306651#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6652/**
6653 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6654 * @hdd_ctx: HDD context
6655 * @request_id: [input] request id
6656 * @pattern_id: [output] pattern id
6657 *
6658 * This function loops through request id to pattern id array
6659 * if the slot is available, store the request id and return pattern id
6660 * if entry exists, return the pattern id
6661 *
6662 * Return: 0 on success and errno on failure
6663 */
6664static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6665 uint32_t request_id,
6666 uint8_t *pattern_id)
6667{
6668 uint32_t i;
6669
6670 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6671 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6672 {
6673 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6674 {
6675 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6676 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6677 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6678 return 0;
6679 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6680 request_id) {
6681 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6682 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6683 return 0;
6684 }
6685 }
6686 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6687 return -EINVAL;
6688}
6689
6690/**
6691 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6692 * @hdd_ctx: HDD context
6693 * @request_id: [input] request id
6694 * @pattern_id: [output] pattern id
6695 *
6696 * This function loops through request id to pattern id array
6697 * reset request id to 0 (slot available again) and
6698 * return pattern id
6699 *
6700 * Return: 0 on success and errno on failure
6701 */
6702static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6703 uint32_t request_id,
6704 uint8_t *pattern_id)
6705{
6706 uint32_t i;
6707
6708 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6709 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6710 {
6711 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6712 {
6713 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6714 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6715 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6716 return 0;
6717 }
6718 }
6719 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6720 return -EINVAL;
6721}
6722
6723
6724/*
6725 * define short names for the global vendor params
6726 * used by __wlan_hdd_cfg80211_offloaded_packets()
6727 */
6728#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6729#define PARAM_REQUEST_ID \
6730 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6731#define PARAM_CONTROL \
6732 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6733#define PARAM_IP_PACKET \
6734 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6735#define PARAM_SRC_MAC_ADDR \
6736 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6737#define PARAM_DST_MAC_ADDR \
6738 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6739#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6740
6741/**
6742 * wlan_hdd_add_tx_ptrn() - add tx pattern
6743 * @adapter: adapter pointer
6744 * @hdd_ctx: hdd context
6745 * @tb: nl attributes
6746 *
6747 * This function reads the NL attributes and forms a AddTxPtrn message
6748 * posts it to SME.
6749 *
6750 */
6751static int
6752wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6753 struct nlattr **tb)
6754{
6755 struct sSirAddPeriodicTxPtrn *add_req;
6756 eHalStatus status;
6757 uint32_t request_id, ret, len;
6758 uint8_t pattern_id = 0;
6759 v_MACADDR_t dst_addr;
6760 uint16_t eth_type = htons(ETH_P_IP);
6761
6762 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6763 {
6764 hddLog(LOGE, FL("Not in Connected state!"));
6765 return -ENOTSUPP;
6766 }
6767
6768 add_req = vos_mem_malloc(sizeof(*add_req));
6769 if (!add_req)
6770 {
6771 hddLog(LOGE, FL("memory allocation failed"));
6772 return -ENOMEM;
6773 }
6774
6775 /* Parse and fetch request Id */
6776 if (!tb[PARAM_REQUEST_ID])
6777 {
6778 hddLog(LOGE, FL("attr request id failed"));
6779 goto fail;
6780 }
6781
6782 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6783 hddLog(LOG1, FL("Request Id: %u"), request_id);
6784 if (request_id == 0)
6785 {
6786 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306787 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306788 }
6789
6790 if (!tb[PARAM_PERIOD])
6791 {
6792 hddLog(LOGE, FL("attr period failed"));
6793 goto fail;
6794 }
6795 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6796 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6797 if (add_req->usPtrnIntervalMs == 0)
6798 {
6799 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6800 goto fail;
6801 }
6802
6803 if (!tb[PARAM_SRC_MAC_ADDR])
6804 {
6805 hddLog(LOGE, FL("attr source mac address failed"));
6806 goto fail;
6807 }
6808 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6809 VOS_MAC_ADDR_SIZE);
6810 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6811 MAC_ADDR_ARRAY(add_req->macAddress));
6812
6813 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6814 VOS_MAC_ADDR_SIZE))
6815 {
6816 hddLog(LOGE,
6817 FL("input src mac address and connected ap bssid are different"));
6818 goto fail;
6819 }
6820
6821 if (!tb[PARAM_DST_MAC_ADDR])
6822 {
6823 hddLog(LOGE, FL("attr dst mac address failed"));
6824 goto fail;
6825 }
6826 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6827 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6828 MAC_ADDR_ARRAY(dst_addr.bytes));
6829
6830 if (!tb[PARAM_IP_PACKET])
6831 {
6832 hddLog(LOGE, FL("attr ip packet failed"));
6833 goto fail;
6834 }
6835 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6836 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6837
6838 if (add_req->ucPtrnSize < 0 ||
6839 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6840 HDD_ETH_HEADER_LEN))
6841 {
6842 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6843 add_req->ucPtrnSize);
6844 goto fail;
6845 }
6846
6847 len = 0;
6848 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6849 len += VOS_MAC_ADDR_SIZE;
6850 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6851 VOS_MAC_ADDR_SIZE);
6852 len += VOS_MAC_ADDR_SIZE;
6853 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6854 len += 2;
6855
6856 /*
6857 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6858 * ------------------------------------------------------------
6859 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6860 * ------------------------------------------------------------
6861 */
6862 vos_mem_copy(&add_req->ucPattern[len],
6863 nla_data(tb[PARAM_IP_PACKET]),
6864 add_req->ucPtrnSize);
6865 add_req->ucPtrnSize += len;
6866
6867 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6868 add_req->ucPattern, add_req->ucPtrnSize);
6869
6870 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6871 if (ret)
6872 {
6873 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6874 goto fail;
6875 }
6876 add_req->ucPtrnId = pattern_id;
6877 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6878
6879 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6880 if (!HAL_STATUS_SUCCESS(status))
6881 {
6882 hddLog(LOGE,
6883 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6884 goto fail;
6885 }
6886
6887 EXIT();
6888 vos_mem_free(add_req);
6889 return 0;
6890
6891fail:
6892 vos_mem_free(add_req);
6893 return -EINVAL;
6894}
6895
6896/**
6897 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6898 * @adapter: adapter pointer
6899 * @hdd_ctx: hdd context
6900 * @tb: nl attributes
6901 *
6902 * This function reads the NL attributes and forms a DelTxPtrn message
6903 * posts it to SME.
6904 *
6905 */
6906static int
6907wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6908 struct nlattr **tb)
6909{
6910 struct sSirDelPeriodicTxPtrn *del_req;
6911 eHalStatus status;
6912 uint32_t request_id, ret;
6913 uint8_t pattern_id = 0;
6914
6915 /* Parse and fetch request Id */
6916 if (!tb[PARAM_REQUEST_ID])
6917 {
6918 hddLog(LOGE, FL("attr request id failed"));
6919 return -EINVAL;
6920 }
6921 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6922 if (request_id == 0)
6923 {
6924 hddLog(LOGE, FL("request_id cannot be zero"));
6925 return -EINVAL;
6926 }
6927
6928 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6929 if (ret)
6930 {
6931 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6932 return -EINVAL;
6933 }
6934
6935 del_req = vos_mem_malloc(sizeof(*del_req));
6936 if (!del_req)
6937 {
6938 hddLog(LOGE, FL("memory allocation failed"));
6939 return -ENOMEM;
6940 }
6941
6942 vos_mem_set(del_req, sizeof(*del_req), 0);
6943 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6944 VOS_MAC_ADDR_SIZE);
6945 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6946 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6947 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6948 request_id, pattern_id, del_req->ucPatternIdBitmap);
6949
6950 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6951 if (!HAL_STATUS_SUCCESS(status))
6952 {
6953 hddLog(LOGE,
6954 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6955 goto fail;
6956 }
6957
6958 EXIT();
6959 vos_mem_free(del_req);
6960 return 0;
6961
6962fail:
6963 vos_mem_free(del_req);
6964 return -EINVAL;
6965}
6966
6967
6968/**
6969 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6970 * @wiphy: Pointer to wireless phy
6971 * @wdev: Pointer to wireless device
6972 * @data: Pointer to data
6973 * @data_len: Data length
6974 *
6975 * Return: 0 on success, negative errno on failure
6976 */
6977static int
6978__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6979 struct wireless_dev *wdev,
6980 const void *data,
6981 int data_len)
6982{
6983 struct net_device *dev = wdev->netdev;
6984 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6985 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6986 struct nlattr *tb[PARAM_MAX + 1];
6987 uint8_t control;
6988 int ret;
6989 static const struct nla_policy policy[PARAM_MAX + 1] =
6990 {
6991 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6992 [PARAM_CONTROL] = { .type = NLA_U32 },
6993 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
6994 .len = VOS_MAC_ADDR_SIZE },
6995 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
6996 .len = VOS_MAC_ADDR_SIZE },
6997 [PARAM_PERIOD] = { .type = NLA_U32 },
6998 };
6999
7000 ENTER();
7001
7002 ret = wlan_hdd_validate_context(hdd_ctx);
7003 if (0 != ret)
7004 {
7005 hddLog(LOGE, FL("HDD context is not valid"));
7006 return ret;
7007 }
7008
7009 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7010 {
7011 hddLog(LOGE,
7012 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7013 return -ENOTSUPP;
7014 }
7015
7016 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7017 {
7018 hddLog(LOGE, FL("Invalid ATTR"));
7019 return -EINVAL;
7020 }
7021
7022 if (!tb[PARAM_CONTROL])
7023 {
7024 hddLog(LOGE, FL("attr control failed"));
7025 return -EINVAL;
7026 }
7027 control = nla_get_u32(tb[PARAM_CONTROL]);
7028 hddLog(LOG1, FL("Control: %d"), control);
7029
7030 if (control == WLAN_START_OFFLOADED_PACKETS)
7031 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7032 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7033 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7034 else
7035 {
7036 hddLog(LOGE, FL("Invalid control: %d"), control);
7037 return -EINVAL;
7038 }
7039}
7040
7041/*
7042 * done with short names for the global vendor params
7043 * used by __wlan_hdd_cfg80211_offloaded_packets()
7044 */
7045#undef PARAM_MAX
7046#undef PARAM_REQUEST_ID
7047#undef PARAM_CONTROL
7048#undef PARAM_IP_PACKET
7049#undef PARAM_SRC_MAC_ADDR
7050#undef PARAM_DST_MAC_ADDR
7051#undef PARAM_PERIOD
7052
7053/**
7054 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7055 * @wiphy: wiphy structure pointer
7056 * @wdev: Wireless device structure pointer
7057 * @data: Pointer to the data received
7058 * @data_len: Length of @data
7059 *
7060 * Return: 0 on success; errno on failure
7061 */
7062static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7063 struct wireless_dev *wdev,
7064 const void *data,
7065 int data_len)
7066{
7067 int ret = 0;
7068
7069 vos_ssr_protect(__func__);
7070 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7071 wdev, data, data_len);
7072 vos_ssr_unprotect(__func__);
7073
7074 return ret;
7075}
7076#endif
7077
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307078static const struct
7079nla_policy
7080qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7081 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7082};
7083
7084/**
7085 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7086 * get link properties like nss, rate flags and operating frequency for
7087 * the connection with the given peer.
7088 * @wiphy: WIPHY structure pointer
7089 * @wdev: Wireless device structure pointer
7090 * @data: Pointer to the data received
7091 * @data_len: Length of the data received
7092 *
7093 * This function return the above link properties on success.
7094 *
7095 * Return: 0 on success and errno on failure
7096 */
7097static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7098 struct wireless_dev *wdev,
7099 const void *data,
7100 int data_len)
7101{
7102 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7103 struct net_device *dev = wdev->netdev;
7104 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7105 hdd_station_ctx_t *hdd_sta_ctx;
7106 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7107 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7108 uint32_t sta_id;
7109 struct sk_buff *reply_skb;
7110 uint32_t rate_flags = 0;
7111 uint8_t nss;
7112 uint8_t final_rate_flags = 0;
7113 uint32_t freq;
7114 v_CONTEXT_t pVosContext = NULL;
7115 ptSapContext pSapCtx = NULL;
7116
7117 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7119 return -EINVAL;
7120 }
7121
7122 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7123 qca_wlan_vendor_attr_policy)) {
7124 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7125 return -EINVAL;
7126 }
7127
7128 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7129 hddLog(VOS_TRACE_LEVEL_ERROR,
7130 FL("Attribute peerMac not provided for mode=%d"),
7131 adapter->device_mode);
7132 return -EINVAL;
7133 }
7134
7135 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7136 sizeof(peer_mac));
7137 hddLog(VOS_TRACE_LEVEL_INFO,
7138 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7139 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7140
7141 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7142 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7143 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7144 if ((hdd_sta_ctx->conn_info.connState !=
7145 eConnectionState_Associated) ||
7146 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7147 VOS_MAC_ADDRESS_LEN)) {
7148 hddLog(VOS_TRACE_LEVEL_ERROR,
7149 FL("Not Associated to mac "MAC_ADDRESS_STR),
7150 MAC_ADDR_ARRAY(peer_mac));
7151 return -EINVAL;
7152 }
7153
7154 nss = 1; //pronto supports only one spatial stream
7155 freq = vos_chan_to_freq(
7156 hdd_sta_ctx->conn_info.operationChannel);
7157 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7158
7159 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7160 adapter->device_mode == WLAN_HDD_SOFTAP) {
7161
7162 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7163 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7164 if(pSapCtx == NULL){
7165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7166 FL("psapCtx is NULL"));
7167 return -ENOENT;
7168 }
7169
7170
7171 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7172 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7173 !vos_is_macaddr_broadcast(
7174 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7175 vos_mem_compare(
7176 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7177 peer_mac, VOS_MAC_ADDRESS_LEN))
7178 break;
7179 }
7180
7181 if (WLAN_MAX_STA_COUNT == sta_id) {
7182 hddLog(VOS_TRACE_LEVEL_ERROR,
7183 FL("No active peer with mac="MAC_ADDRESS_STR),
7184 MAC_ADDR_ARRAY(peer_mac));
7185 return -EINVAL;
7186 }
7187
7188 nss = 1; //pronto supports only one spatial stream
7189 freq = vos_chan_to_freq(
7190 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7191 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7192 } else {
7193 hddLog(VOS_TRACE_LEVEL_ERROR,
7194 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7195 MAC_ADDR_ARRAY(peer_mac));
7196 return -EINVAL;
7197 }
7198
7199 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7200 if (rate_flags & eHAL_TX_RATE_VHT80) {
7201 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7202 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7203 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7204 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7205 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7206 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7207 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7208 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7209 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7210 if (rate_flags & eHAL_TX_RATE_HT40)
7211 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7212 }
7213
7214 if (rate_flags & eHAL_TX_RATE_SGI) {
7215 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7216 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7217 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7218 }
7219 }
7220
7221 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7222 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7223
7224 if (NULL == reply_skb) {
7225 hddLog(VOS_TRACE_LEVEL_ERROR,
7226 FL("getLinkProperties: skb alloc failed"));
7227 return -EINVAL;
7228 }
7229
7230 if (nla_put_u8(reply_skb,
7231 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7232 nss) ||
7233 nla_put_u8(reply_skb,
7234 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7235 final_rate_flags) ||
7236 nla_put_u32(reply_skb,
7237 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7238 freq)) {
7239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7240 kfree_skb(reply_skb);
7241 return -EINVAL;
7242 }
7243
7244 return cfg80211_vendor_cmd_reply(reply_skb);
7245}
7246
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307247#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7248#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7249#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7250#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307251#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7252 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307253
7254/**
7255 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7256 * vendor command
7257 *
7258 * @wiphy: wiphy device pointer
7259 * @wdev: wireless device pointer
7260 * @data: Vendor command data buffer
7261 * @data_len: Buffer length
7262 *
7263 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7264 *
7265 * Return: EOK or other error codes.
7266 */
7267
7268static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7269 struct wireless_dev *wdev,
7270 const void *data,
7271 int data_len)
7272{
7273 struct net_device *dev = wdev->netdev;
7274 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7275 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7276 hdd_station_ctx_t *pHddStaCtx;
7277 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7278 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307279 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307280 eHalStatus status;
7281 int ret_val;
7282 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7283 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7284 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307285 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7286 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7287 { .type = NLA_U32},
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307288 };
7289
7290 ENTER();
7291
7292 if (VOS_FTM_MODE == hdd_get_conparam()) {
7293 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7294 return -EINVAL;
7295 }
7296
7297 ret_val = wlan_hdd_validate_context(pHddCtx);
7298 if (ret_val) {
7299 return ret_val;
7300 }
7301
7302 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7303
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307304 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7305 hddLog(LOGE, FL("Invalid ATTR"));
7306 return -EINVAL;
7307 }
7308
7309 /* check the Wifi Capability */
7310 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7311 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7312 {
7313 hddLog(VOS_TRACE_LEVEL_ERROR,
7314 FL("WIFICONFIG not supported by Firmware"));
7315 return -EINVAL;
7316 }
7317
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307318 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7319 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7320 modifyRoamParamsReq.value =
7321 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7322
7323 if (eHAL_STATUS_SUCCESS !=
7324 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7325 {
7326 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7327 ret_val = -EINVAL;
7328 }
7329 return ret_val;
7330 }
7331
7332 /* Moved this down in order to provide provision to set beacon
7333 * miss penalty count irrespective of connection state.
7334 */
7335 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7336 hddLog(LOGE, FL("Not in Connected state!"));
7337 return -ENOTSUPP;
7338 }
7339
7340 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307341
7342 if (!pReq) {
7343 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7344 "%s: Not able to allocate memory for tSetWifiConfigParams",
7345 __func__);
7346 return eHAL_STATUS_E_MALLOC_FAILED;
7347 }
7348
7349 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7350
7351 pReq->sessionId = pAdapter->sessionId;
7352 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7353
7354 if (tb[PARAM_MODULATED_DTIM]) {
7355 pReq->paramValue = nla_get_u32(
7356 tb[PARAM_MODULATED_DTIM]);
7357 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7358 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307359 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307360 hdd_set_pwrparams(pHddCtx);
7361 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7362 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7363
7364 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7365 iw_full_power_cbfn, pAdapter,
7366 eSME_FULL_PWR_NEEDED_BY_HDD);
7367 }
7368 else
7369 {
7370 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7371 }
7372 }
7373
7374 if (tb[PARAM_STATS_AVG_FACTOR]) {
7375 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7376 pReq->paramValue = nla_get_u16(
7377 tb[PARAM_STATS_AVG_FACTOR]);
7378 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7379 pReq->paramType, pReq->paramValue);
7380 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7381
7382 if (eHAL_STATUS_SUCCESS != status)
7383 {
7384 vos_mem_free(pReq);
7385 pReq = NULL;
7386 ret_val = -EPERM;
7387 return ret_val;
7388 }
7389 }
7390
7391
7392 if (tb[PARAM_GUARD_TIME]) {
7393 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7394 pReq->paramValue = nla_get_u32(
7395 tb[PARAM_GUARD_TIME]);
7396 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7397 pReq->paramType, pReq->paramValue);
7398 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7399
7400 if (eHAL_STATUS_SUCCESS != status)
7401 {
7402 vos_mem_free(pReq);
7403 pReq = NULL;
7404 ret_val = -EPERM;
7405 return ret_val;
7406 }
7407
7408 }
7409
7410 EXIT();
7411 return ret_val;
7412}
7413
7414/**
7415 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7416 * vendor command
7417 *
7418 * @wiphy: wiphy device pointer
7419 * @wdev: wireless device pointer
7420 * @data: Vendor command data buffer
7421 * @data_len: Buffer length
7422 *
7423 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7424 *
7425 * Return: EOK or other error codes.
7426 */
7427static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7428 struct wireless_dev *wdev,
7429 const void *data,
7430 int data_len)
7431{
7432 int ret;
7433
7434 vos_ssr_protect(__func__);
7435 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7436 data, data_len);
7437 vos_ssr_unprotect(__func__);
7438
7439 return ret;
7440}
Sunil Duttc69bccb2014-05-26 21:30:20 +05307441const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7442{
Mukul Sharma2a271632014-10-13 14:59:01 +05307443 {
7444 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7445 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7446 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7447 WIPHY_VENDOR_CMD_NEED_NETDEV |
7448 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307449 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307450 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307451
7452 {
7453 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7454 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7455 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7456 WIPHY_VENDOR_CMD_NEED_NETDEV |
7457 WIPHY_VENDOR_CMD_NEED_RUNNING,
7458 .doit = wlan_hdd_cfg80211_nan_request
7459 },
7460
Sunil Duttc69bccb2014-05-26 21:30:20 +05307461#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7462 {
7463 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7464 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7465 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7466 WIPHY_VENDOR_CMD_NEED_NETDEV |
7467 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307468 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307469 },
7470
7471 {
7472 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7473 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7474 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7475 WIPHY_VENDOR_CMD_NEED_NETDEV |
7476 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307477 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307478 },
7479
7480 {
7481 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7482 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7483 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7484 WIPHY_VENDOR_CMD_NEED_NETDEV |
7485 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307486 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307487 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307488#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307489#ifdef WLAN_FEATURE_EXTSCAN
7490 {
7491 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7492 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7493 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7494 WIPHY_VENDOR_CMD_NEED_NETDEV |
7495 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307496 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307497 },
7498 {
7499 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7500 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7501 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7502 WIPHY_VENDOR_CMD_NEED_NETDEV |
7503 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307504 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307505 },
7506 {
7507 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7508 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7509 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7510 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307511 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307512 },
7513 {
7514 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7515 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7516 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7517 WIPHY_VENDOR_CMD_NEED_NETDEV |
7518 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307519 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307520 },
7521 {
7522 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7523 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7524 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7525 WIPHY_VENDOR_CMD_NEED_NETDEV |
7526 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307527 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307528 },
7529 {
7530 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7531 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7532 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7533 WIPHY_VENDOR_CMD_NEED_NETDEV |
7534 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307535 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307536 },
7537 {
7538 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7539 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7540 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7541 WIPHY_VENDOR_CMD_NEED_NETDEV |
7542 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307543 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307544 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307545 {
7546 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7547 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7548 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7549 WIPHY_VENDOR_CMD_NEED_NETDEV |
7550 WIPHY_VENDOR_CMD_NEED_RUNNING,
7551 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7552 },
7553 {
7554 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7555 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7556 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7557 WIPHY_VENDOR_CMD_NEED_NETDEV |
7558 WIPHY_VENDOR_CMD_NEED_RUNNING,
7559 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7560 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307561#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307562/*EXT TDLS*/
7563 {
7564 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7565 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7566 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7567 WIPHY_VENDOR_CMD_NEED_NETDEV |
7568 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307569 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307570 },
7571 {
7572 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7573 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7574 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7575 WIPHY_VENDOR_CMD_NEED_NETDEV |
7576 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307577 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307578 },
7579 {
7580 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7581 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7582 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7583 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307584 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307585 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307586 {
7587 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7588 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7589 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7590 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307591 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307592 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307593 {
7594 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7595 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7596 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7597 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307598 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307599 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307600 {
7601 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7602 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7603 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7604 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307605 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307606 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307607 {
7608 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7609 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7610 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7611 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307612 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307613 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307614 {
7615 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307616 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7617 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7618 WIPHY_VENDOR_CMD_NEED_NETDEV |
7619 WIPHY_VENDOR_CMD_NEED_RUNNING,
7620 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7621 },
7622 {
7623 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307624 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7625 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7626 WIPHY_VENDOR_CMD_NEED_NETDEV |
7627 WIPHY_VENDOR_CMD_NEED_RUNNING,
7628 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307629 },
7630 {
7631 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7632 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7633 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7634 WIPHY_VENDOR_CMD_NEED_NETDEV,
7635 .doit = wlan_hdd_cfg80211_wifi_logger_start
7636 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307637 {
7638 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7639 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7640 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7641 WIPHY_VENDOR_CMD_NEED_NETDEV|
7642 WIPHY_VENDOR_CMD_NEED_RUNNING,
7643 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307644 },
7645 {
7646 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7647 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7648 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7649 WIPHY_VENDOR_CMD_NEED_NETDEV |
7650 WIPHY_VENDOR_CMD_NEED_RUNNING,
7651 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307652 },
7653 {
7654 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7655 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7656 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7657 WIPHY_VENDOR_CMD_NEED_NETDEV |
7658 WIPHY_VENDOR_CMD_NEED_RUNNING,
7659 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307660 },
7661#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7662 {
7663 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7664 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7665 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7666 WIPHY_VENDOR_CMD_NEED_NETDEV |
7667 WIPHY_VENDOR_CMD_NEED_RUNNING,
7668 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307669 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307670#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307671 {
7672 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7673 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7674 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7675 WIPHY_VENDOR_CMD_NEED_NETDEV |
7676 WIPHY_VENDOR_CMD_NEED_RUNNING,
7677 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307678 },
7679 {
7680 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7681 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7682 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7683 WIPHY_VENDOR_CMD_NEED_NETDEV |
7684 WIPHY_VENDOR_CMD_NEED_RUNNING,
7685 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307686 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05307687};
7688
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007689/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307690static const
7691struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007692{
7693#ifdef FEATURE_WLAN_CH_AVOID
7694 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307695 .vendor_id = QCA_NL80211_VENDOR_ID,
7696 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007697 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307698#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7699#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7700 {
7701 /* Index = 1*/
7702 .vendor_id = QCA_NL80211_VENDOR_ID,
7703 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7704 },
7705 {
7706 /* Index = 2*/
7707 .vendor_id = QCA_NL80211_VENDOR_ID,
7708 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7709 },
7710 {
7711 /* Index = 3*/
7712 .vendor_id = QCA_NL80211_VENDOR_ID,
7713 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7714 },
7715 {
7716 /* Index = 4*/
7717 .vendor_id = QCA_NL80211_VENDOR_ID,
7718 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7719 },
7720 {
7721 /* Index = 5*/
7722 .vendor_id = QCA_NL80211_VENDOR_ID,
7723 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7724 },
7725 {
7726 /* Index = 6*/
7727 .vendor_id = QCA_NL80211_VENDOR_ID,
7728 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7729 },
7730#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307731#ifdef WLAN_FEATURE_EXTSCAN
7732 {
7733 .vendor_id = QCA_NL80211_VENDOR_ID,
7734 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7735 },
7736 {
7737 .vendor_id = QCA_NL80211_VENDOR_ID,
7738 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7739 },
7740 {
7741 .vendor_id = QCA_NL80211_VENDOR_ID,
7742 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7743 },
7744 {
7745 .vendor_id = QCA_NL80211_VENDOR_ID,
7746 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7747 },
7748 {
7749 .vendor_id = QCA_NL80211_VENDOR_ID,
7750 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7751 },
7752 {
7753 .vendor_id = QCA_NL80211_VENDOR_ID,
7754 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7755 },
7756 {
7757 .vendor_id = QCA_NL80211_VENDOR_ID,
7758 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7759 },
7760 {
7761 .vendor_id = QCA_NL80211_VENDOR_ID,
7762 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7763 },
7764 {
7765 .vendor_id = QCA_NL80211_VENDOR_ID,
7766 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7767 },
7768 {
7769 .vendor_id = QCA_NL80211_VENDOR_ID,
7770 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7771 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307772 {
7773 .vendor_id = QCA_NL80211_VENDOR_ID,
7774 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7775 },
7776 {
7777 .vendor_id = QCA_NL80211_VENDOR_ID,
7778 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7779 },
7780 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7781 .vendor_id = QCA_NL80211_VENDOR_ID,
7782 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7783 },
7784 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7785 .vendor_id = QCA_NL80211_VENDOR_ID,
7786 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7787 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307788#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307789/*EXT TDLS*/
7790 {
7791 .vendor_id = QCA_NL80211_VENDOR_ID,
7792 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7793 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307794 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7795 .vendor_id = QCA_NL80211_VENDOR_ID,
7796 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7797 },
7798
Srinivas Dasari030bad32015-02-18 23:23:54 +05307799
7800 {
7801 .vendor_id = QCA_NL80211_VENDOR_ID,
7802 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7803 },
7804
Sushant Kaushik084f6592015-09-10 13:11:56 +05307805 {
7806 .vendor_id = QCA_NL80211_VENDOR_ID,
7807 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307808 },
7809 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7810 .vendor_id = QCA_NL80211_VENDOR_ID,
7811 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7812 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05307813 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
7814 .vendor_id = QCA_NL80211_VENDOR_ID,
7815 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
7816 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307817
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007818};
7819
Jeff Johnson295189b2012-06-20 16:38:30 -07007820/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307821 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307822 * This function is called by hdd_wlan_startup()
7823 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307824 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007825 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307826struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007827{
7828 struct wiphy *wiphy;
7829 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307830 /*
7831 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007832 */
7833 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7834
7835 if (!wiphy)
7836 {
7837 /* Print error and jump into err label and free the memory */
7838 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7839 return NULL;
7840 }
7841
Sunil Duttc69bccb2014-05-26 21:30:20 +05307842
Jeff Johnson295189b2012-06-20 16:38:30 -07007843 return wiphy;
7844}
7845
7846/*
7847 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307848 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007849 * private ioctl to change the band value
7850 */
7851int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7852{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307853 int i, j;
7854 eNVChannelEnabledType channelEnabledState;
7855
Jeff Johnsone7245742012-09-05 17:12:55 -07007856 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307857
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307858 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007859 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307860
7861 if (NULL == wiphy->bands[i])
7862 {
7863 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7864 __func__, i);
7865 continue;
7866 }
7867
7868 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7869 {
7870 struct ieee80211_supported_band *band = wiphy->bands[i];
7871
7872 channelEnabledState = vos_nv_getChannelEnabledState(
7873 band->channels[j].hw_value);
7874
7875 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7876 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307877 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307878 continue;
7879 }
7880 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7881 {
7882 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7883 continue;
7884 }
7885
7886 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7887 NV_CHANNEL_INVALID == channelEnabledState)
7888 {
7889 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7890 }
7891 else if (NV_CHANNEL_DFS == channelEnabledState)
7892 {
7893 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7894 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7895 }
7896 else
7897 {
7898 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7899 |IEEE80211_CHAN_RADAR);
7900 }
7901 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007902 }
7903 return 0;
7904}
7905/*
7906 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307907 * This function is called by hdd_wlan_startup()
7908 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007909 * This function is used to initialize and register wiphy structure.
7910 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307911int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007912 struct wiphy *wiphy,
7913 hdd_config_t *pCfg
7914 )
7915{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307916 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307917 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7918
Jeff Johnsone7245742012-09-05 17:12:55 -07007919 ENTER();
7920
Jeff Johnson295189b2012-06-20 16:38:30 -07007921 /* Now bind the underlying wlan device with wiphy */
7922 set_wiphy_dev(wiphy, dev);
7923
7924 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007925
Kiet Lam6c583332013-10-14 05:37:09 +05307926#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007927 /* the flag for the other case would be initialzed in
7928 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05307929#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7930 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
7931#else
Amar Singhal0a402232013-10-11 20:57:16 -07007932 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307933#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05307934#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007935
Amar Singhalfddc28c2013-09-05 13:03:40 -07007936 /* This will disable updating of NL channels from passive to
7937 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307938#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7939 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7940#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007941 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307942#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007943
Amar Singhala49cbc52013-10-08 18:37:44 -07007944
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007945#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007946 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7947 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7948 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007949 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307950#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05307951 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307952#else
7953 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7954#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007955#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007956
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007957#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007958 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007959#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007960 || pCfg->isFastRoamIniFeatureEnabled
7961#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007962#ifdef FEATURE_WLAN_ESE
7963 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007964#endif
7965 )
7966 {
7967 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7968 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007969#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007970#ifdef FEATURE_WLAN_TDLS
7971 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7972 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7973#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307974#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307975 if (pCfg->configPNOScanSupport)
7976 {
7977 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7978 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7979 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7980 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7981 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307982#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007983
Abhishek Singh10d85972015-04-17 10:27:23 +05307984#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7985 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7986#endif
7987
Amar Singhalfddc28c2013-09-05 13:03:40 -07007988#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007989 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
7990 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07007991 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007992 driver need to determine what to do with both
7993 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07007994
7995 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07007996#else
7997 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007998#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007999
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308000 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8001
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308002 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008003
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308004 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8005
Jeff Johnson295189b2012-06-20 16:38:30 -07008006 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308007 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8008 | BIT(NL80211_IFTYPE_ADHOC)
8009 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8010 | BIT(NL80211_IFTYPE_P2P_GO)
8011 | BIT(NL80211_IFTYPE_AP);
8012
8013 if (VOS_MONITOR_MODE == hdd_get_conparam())
8014 {
8015 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8016 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008017
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308018 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008019 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308020#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8021 if( pCfg->enableMCC )
8022 {
8023 /* Currently, supports up to two channels */
8024 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008025
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308026 if( !pCfg->allowMCCGODiffBI )
8027 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008028
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308029 }
8030 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8031 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008032#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308033 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008034
Jeff Johnson295189b2012-06-20 16:38:30 -07008035 /* Before registering we need to update the ht capabilitied based
8036 * on ini values*/
8037 if( !pCfg->ShortGI20MhzEnable )
8038 {
8039 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8040 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008041 }
8042
8043 if( !pCfg->ShortGI40MhzEnable )
8044 {
8045 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8046 }
8047
8048 if( !pCfg->nChannelBondingMode5GHz )
8049 {
8050 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8051 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308052 /*
8053 * In case of static linked driver at the time of driver unload,
8054 * module exit doesn't happens. Module cleanup helps in cleaning
8055 * of static memory.
8056 * If driver load happens statically, at the time of driver unload,
8057 * wiphy flags don't get reset because of static memory.
8058 * It's better not to store channel in static memory.
8059 */
8060 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8061 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8062 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8063 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8064 {
8065 hddLog(VOS_TRACE_LEVEL_ERROR,
8066 FL("Not enough memory to allocate channels"));
8067 return -ENOMEM;
8068 }
8069 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8070 &hdd_channels_2_4_GHZ[0],
8071 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008072
Agrawal Ashish97dec502015-11-26 20:20:58 +05308073 if (true == hdd_is_5g_supported(pHddCtx))
8074 {
8075 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8076 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8077 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8078 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8079 {
8080 hddLog(VOS_TRACE_LEVEL_ERROR,
8081 FL("Not enough memory to allocate channels"));
8082 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8083 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8084 return -ENOMEM;
8085 }
8086 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8087 &hdd_channels_5_GHZ[0],
8088 sizeof(hdd_channels_5_GHZ));
8089 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308090
8091 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8092 {
8093
8094 if (NULL == wiphy->bands[i])
8095 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308096 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308097 __func__, i);
8098 continue;
8099 }
8100
8101 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8102 {
8103 struct ieee80211_supported_band *band = wiphy->bands[i];
8104
8105 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8106 {
8107 // Enable social channels for P2P
8108 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8109 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8110 else
8111 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8112 continue;
8113 }
8114 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8115 {
8116 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8117 continue;
8118 }
8119 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008120 }
8121 /*Initialise the supported cipher suite details*/
8122 wiphy->cipher_suites = hdd_cipher_suites;
8123 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8124
8125 /*signal strength in mBm (100*dBm) */
8126 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8127
8128#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308129 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008130#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008131
Sunil Duttc69bccb2014-05-26 21:30:20 +05308132 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8133 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008134 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8135 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8136
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308137 EXIT();
8138 return 0;
8139}
8140
8141/* In this function we are registering wiphy. */
8142int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8143{
8144 ENTER();
8145 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008146 if (0 > wiphy_register(wiphy))
8147 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308148 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008149 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8150 return -EIO;
8151 }
8152
8153 EXIT();
8154 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308155}
Jeff Johnson295189b2012-06-20 16:38:30 -07008156
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308157/* In this function we are updating channel list when,
8158 regulatory domain is FCC and country code is US.
8159 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8160 As per FCC smart phone is not a indoor device.
8161 GO should not opeate on indoor channels */
8162void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8163{
8164 int j;
8165 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8166 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8167 //Default counrtycode from NV at the time of wiphy initialization.
8168 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8169 &defaultCountryCode[0]))
8170 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008171 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308172 }
8173 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8174 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308175 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8176 {
8177 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8178 return;
8179 }
8180 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8181 {
8182 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8183 // Mark UNII -1 band channel as passive
8184 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8185 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8186 }
8187 }
8188}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308189/* This function registers for all frame which supplicant is interested in */
8190void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008191{
Jeff Johnson295189b2012-06-20 16:38:30 -07008192 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8193 /* Register for all P2P action, public action etc frames */
8194 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008195 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308196 /* Register frame indication call back */
8197 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008198 /* Right now we are registering these frame when driver is getting
8199 initialized. Once we will move to 2.6.37 kernel, in which we have
8200 frame register ops, we will move this code as a part of that */
8201 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308202 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008203 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8204
8205 /* GAS Initial Response */
8206 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8207 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308208
Jeff Johnson295189b2012-06-20 16:38:30 -07008209 /* GAS Comeback Request */
8210 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8211 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8212
8213 /* GAS Comeback Response */
8214 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8215 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8216
8217 /* P2P Public Action */
8218 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308219 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008220 P2P_PUBLIC_ACTION_FRAME_SIZE );
8221
8222 /* P2P Action */
8223 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8224 (v_U8_t*)P2P_ACTION_FRAME,
8225 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008226
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308227 /* WNM BSS Transition Request frame */
8228 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8229 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8230 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008231
8232 /* WNM-Notification */
8233 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8234 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8235 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008236}
8237
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308238void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008239{
Jeff Johnson295189b2012-06-20 16:38:30 -07008240 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8241 /* Register for all P2P action, public action etc frames */
8242 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8243
Jeff Johnsone7245742012-09-05 17:12:55 -07008244 ENTER();
8245
Jeff Johnson295189b2012-06-20 16:38:30 -07008246 /* Right now we are registering these frame when driver is getting
8247 initialized. Once we will move to 2.6.37 kernel, in which we have
8248 frame register ops, we will move this code as a part of that */
8249 /* GAS Initial Request */
8250
8251 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8252 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8253
8254 /* GAS Initial Response */
8255 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8256 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308257
Jeff Johnson295189b2012-06-20 16:38:30 -07008258 /* GAS Comeback Request */
8259 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8260 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8261
8262 /* GAS Comeback Response */
8263 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8264 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8265
8266 /* P2P Public Action */
8267 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308268 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008269 P2P_PUBLIC_ACTION_FRAME_SIZE );
8270
8271 /* P2P Action */
8272 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8273 (v_U8_t*)P2P_ACTION_FRAME,
8274 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008275 /* WNM-Notification */
8276 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8277 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8278 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008279}
8280
8281#ifdef FEATURE_WLAN_WAPI
8282void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308283 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008284{
8285 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8286 tCsrRoamSetKey setKey;
8287 v_BOOL_t isConnected = TRUE;
8288 int status = 0;
8289 v_U32_t roamId= 0xFF;
8290 tANI_U8 *pKeyPtr = NULL;
8291 int n = 0;
8292
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308293 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8294 __func__, hdd_device_modetoString(pAdapter->device_mode),
8295 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008296
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308297 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008298 setKey.keyId = key_index; // Store Key ID
8299 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8300 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8301 setKey.paeRole = 0 ; // the PAE role
8302 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8303 {
8304 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8305 }
8306 else
8307 {
8308 isConnected = hdd_connIsConnected(pHddStaCtx);
8309 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8310 }
8311 setKey.keyLength = key_Len;
8312 pKeyPtr = setKey.Key;
8313 memcpy( pKeyPtr, key, key_Len);
8314
Arif Hussain6d2a3322013-11-17 19:50:10 -08008315 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008316 __func__, key_Len);
8317 for (n = 0 ; n < key_Len; n++)
8318 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8319 __func__,n,setKey.Key[n]);
8320
8321 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8322 if ( isConnected )
8323 {
8324 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8325 pAdapter->sessionId, &setKey, &roamId );
8326 }
8327 if ( status != 0 )
8328 {
8329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8330 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8331 __LINE__, status );
8332 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8333 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308334 /* Need to clear any trace of key value in the memory.
8335 * Thus zero out the memory even though it is local
8336 * variable.
8337 */
8338 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008339}
8340#endif /* FEATURE_WLAN_WAPI*/
8341
8342#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308343int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008344 beacon_data_t **ppBeacon,
8345 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008346#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308347int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008348 beacon_data_t **ppBeacon,
8349 struct cfg80211_beacon_data *params,
8350 int dtim_period)
8351#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308352{
Jeff Johnson295189b2012-06-20 16:38:30 -07008353 int size;
8354 beacon_data_t *beacon = NULL;
8355 beacon_data_t *old = NULL;
8356 int head_len,tail_len;
8357
Jeff Johnsone7245742012-09-05 17:12:55 -07008358 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008359 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308360 {
8361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8362 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008363 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308364 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008365
8366 old = pAdapter->sessionCtx.ap.beacon;
8367
8368 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308369 {
8370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8371 FL("session(%d) old and new heads points to NULL"),
8372 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008373 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308374 }
8375
8376 if (params->tail && !params->tail_len)
8377 {
8378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8379 FL("tail_len is zero but tail is not NULL"));
8380 return -EINVAL;
8381 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008382
Jeff Johnson295189b2012-06-20 16:38:30 -07008383#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8384 /* Kernel 3.0 is not updating dtim_period for set beacon */
8385 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308386 {
8387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8388 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008389 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308390 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008391#endif
8392
8393 if(params->head)
8394 head_len = params->head_len;
8395 else
8396 head_len = old->head_len;
8397
8398 if(params->tail || !old)
8399 tail_len = params->tail_len;
8400 else
8401 tail_len = old->tail_len;
8402
8403 size = sizeof(beacon_data_t) + head_len + tail_len;
8404
8405 beacon = kzalloc(size, GFP_KERNEL);
8406
8407 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308408 {
8409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8410 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008411 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308412 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008413
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008414#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008415 if(params->dtim_period || !old )
8416 beacon->dtim_period = params->dtim_period;
8417 else
8418 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008419#else
8420 if(dtim_period || !old )
8421 beacon->dtim_period = dtim_period;
8422 else
8423 beacon->dtim_period = old->dtim_period;
8424#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308425
Jeff Johnson295189b2012-06-20 16:38:30 -07008426 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8427 beacon->tail = beacon->head + head_len;
8428 beacon->head_len = head_len;
8429 beacon->tail_len = tail_len;
8430
8431 if(params->head) {
8432 memcpy (beacon->head,params->head,beacon->head_len);
8433 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308434 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07008435 if(old)
8436 memcpy (beacon->head,old->head,beacon->head_len);
8437 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308438
Jeff Johnson295189b2012-06-20 16:38:30 -07008439 if(params->tail) {
8440 memcpy (beacon->tail,params->tail,beacon->tail_len);
8441 }
8442 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308443 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07008444 memcpy (beacon->tail,old->tail,beacon->tail_len);
8445 }
8446
8447 *ppBeacon = beacon;
8448
8449 kfree(old);
8450
8451 return 0;
8452
8453}
Jeff Johnson295189b2012-06-20 16:38:30 -07008454
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308455v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8456#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8457 const v_U8_t *pIes,
8458#else
8459 v_U8_t *pIes,
8460#endif
8461 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008462{
8463 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308464 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308466
Jeff Johnson295189b2012-06-20 16:38:30 -07008467 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308468 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008469 elem_id = ptr[0];
8470 elem_len = ptr[1];
8471 left -= 2;
8472 if(elem_len > left)
8473 {
8474 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008475 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008476 eid,elem_len,left);
8477 return NULL;
8478 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308479 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 {
8481 return ptr;
8482 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308483
Jeff Johnson295189b2012-06-20 16:38:30 -07008484 left -= elem_len;
8485 ptr += (elem_len + 2);
8486 }
8487 return NULL;
8488}
8489
Jeff Johnson295189b2012-06-20 16:38:30 -07008490/* Check if rate is 11g rate or not */
8491static int wlan_hdd_rate_is_11g(u8 rate)
8492{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008493 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008494 u8 i;
8495 for (i = 0; i < 8; i++)
8496 {
8497 if(rate == gRateArray[i])
8498 return TRUE;
8499 }
8500 return FALSE;
8501}
8502
8503/* Check for 11g rate and set proper 11g only mode */
8504static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8505 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8506{
8507 u8 i, num_rates = pIe[0];
8508
8509 pIe += 1;
8510 for ( i = 0; i < num_rates; i++)
8511 {
8512 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8513 {
8514 /* If rate set have 11g rate than change the mode to 11G */
8515 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8516 if (pIe[i] & BASIC_RATE_MASK)
8517 {
8518 /* If we have 11g rate as basic rate, it means mode
8519 is 11g only mode.
8520 */
8521 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8522 *pCheckRatesfor11g = FALSE;
8523 }
8524 }
8525 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8526 {
8527 *require_ht = TRUE;
8528 }
8529 }
8530 return;
8531}
8532
8533static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8534{
8535 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8536 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8537 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8538 u8 checkRatesfor11g = TRUE;
8539 u8 require_ht = FALSE;
8540 u8 *pIe=NULL;
8541
8542 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8543
8544 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8545 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8546 if (pIe != NULL)
8547 {
8548 pIe += 1;
8549 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8550 &pConfig->SapHw_mode);
8551 }
8552
8553 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8554 WLAN_EID_EXT_SUPP_RATES);
8555 if (pIe != NULL)
8556 {
8557
8558 pIe += 1;
8559 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8560 &pConfig->SapHw_mode);
8561 }
8562
8563 if( pConfig->channel > 14 )
8564 {
8565 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8566 }
8567
8568 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8569 WLAN_EID_HT_CAPABILITY);
8570
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308571 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008572 {
8573 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8574 if(require_ht)
8575 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8576 }
8577}
8578
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308579static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8580 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8581{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008582 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308583 v_U8_t *pIe = NULL;
8584 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8585
8586 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8587 pBeacon->tail, pBeacon->tail_len);
8588
8589 if (pIe)
8590 {
8591 ielen = pIe[1] + 2;
8592 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8593 {
8594 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8595 }
8596 else
8597 {
8598 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8599 return -EINVAL;
8600 }
8601 *total_ielen += ielen;
8602 }
8603 return 0;
8604}
8605
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008606static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8607 v_U8_t *genie, v_U8_t *total_ielen)
8608{
8609 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8610 int left = pBeacon->tail_len;
8611 v_U8_t *ptr = pBeacon->tail;
8612 v_U8_t elem_id, elem_len;
8613 v_U16_t ielen = 0;
8614
8615 if ( NULL == ptr || 0 == left )
8616 return;
8617
8618 while (left >= 2)
8619 {
8620 elem_id = ptr[0];
8621 elem_len = ptr[1];
8622 left -= 2;
8623 if (elem_len > left)
8624 {
8625 hddLog( VOS_TRACE_LEVEL_ERROR,
8626 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8627 elem_id, elem_len, left);
8628 return;
8629 }
8630 if (IE_EID_VENDOR == elem_id)
8631 {
8632 /* skipping the VSIE's which we don't want to include or
8633 * it will be included by existing code
8634 */
8635 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8636#ifdef WLAN_FEATURE_WFD
8637 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8638#endif
8639 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8640 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8641 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8642 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8643 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8644 {
8645 ielen = ptr[1] + 2;
8646 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8647 {
8648 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8649 *total_ielen += ielen;
8650 }
8651 else
8652 {
8653 hddLog( VOS_TRACE_LEVEL_ERROR,
8654 "IE Length is too big "
8655 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8656 elem_id, elem_len, *total_ielen);
8657 }
8658 }
8659 }
8660
8661 left -= elem_len;
8662 ptr += (elem_len + 2);
8663 }
8664 return;
8665}
8666
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008667#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008668static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8669 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008670#else
8671static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8672 struct cfg80211_beacon_data *params)
8673#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008674{
8675 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308676 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008677 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008678 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008679
8680 genie = vos_mem_malloc(MAX_GENIE_LEN);
8681
8682 if(genie == NULL) {
8683
8684 return -ENOMEM;
8685 }
8686
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308687 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8688 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008689 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308690 hddLog(LOGE,
8691 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308692 ret = -EINVAL;
8693 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008694 }
8695
8696#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308697 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8698 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8699 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308700 hddLog(LOGE,
8701 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308702 ret = -EINVAL;
8703 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008704 }
8705#endif
8706
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308707 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8708 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008709 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308710 hddLog(LOGE,
8711 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308712 ret = -EINVAL;
8713 goto done;
8714 }
8715
8716 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8717 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008718 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008719 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008720
8721 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8722 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8723 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8724 {
8725 hddLog(LOGE,
8726 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008727 ret = -EINVAL;
8728 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008729 }
8730
8731 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8732 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8733 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8734 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8735 ==eHAL_STATUS_FAILURE)
8736 {
8737 hddLog(LOGE,
8738 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008739 ret = -EINVAL;
8740 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008741 }
8742
8743 // Added for ProResp IE
8744 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
8745 {
8746 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
8747 u8 probe_rsp_ie_len[3] = {0};
8748 u8 counter = 0;
8749 /* Check Probe Resp Length if it is greater then 255 then Store
8750 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8751 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8752 Store More then 255 bytes into One Variable.
8753 */
8754 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8755 {
8756 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8757 {
8758 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8759 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8760 }
8761 else
8762 {
8763 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8764 rem_probe_resp_ie_len = 0;
8765 }
8766 }
8767
8768 rem_probe_resp_ie_len = 0;
8769
8770 if (probe_rsp_ie_len[0] > 0)
8771 {
8772 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8773 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
8774 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8775 probe_rsp_ie_len[0], NULL,
8776 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8777 {
8778 hddLog(LOGE,
8779 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008780 ret = -EINVAL;
8781 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008782 }
8783 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8784 }
8785
8786 if (probe_rsp_ie_len[1] > 0)
8787 {
8788 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8789 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
8790 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8791 probe_rsp_ie_len[1], NULL,
8792 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8793 {
8794 hddLog(LOGE,
8795 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008796 ret = -EINVAL;
8797 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008798 }
8799 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8800 }
8801
8802 if (probe_rsp_ie_len[2] > 0)
8803 {
8804 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8805 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
8806 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8807 probe_rsp_ie_len[2], NULL,
8808 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8809 {
8810 hddLog(LOGE,
8811 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008812 ret = -EINVAL;
8813 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008814 }
8815 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8816 }
8817
8818 if (probe_rsp_ie_len[1] == 0 )
8819 {
8820 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8821 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8822 eANI_BOOLEAN_FALSE) )
8823 {
8824 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008825 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008826 }
8827 }
8828
8829 if (probe_rsp_ie_len[2] == 0 )
8830 {
8831 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8832 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8833 eANI_BOOLEAN_FALSE) )
8834 {
8835 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008836 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008837 }
8838 }
8839
8840 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8841 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8842 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8843 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8844 == eHAL_STATUS_FAILURE)
8845 {
8846 hddLog(LOGE,
8847 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008848 ret = -EINVAL;
8849 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008850 }
8851 }
8852 else
8853 {
8854 // Reset WNI_CFG_PROBE_RSP Flags
8855 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8856
8857 hddLog(VOS_TRACE_LEVEL_INFO,
8858 "%s: No Probe Response IE received in set beacon",
8859 __func__);
8860 }
8861
8862 // Added for AssocResp IE
8863 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
8864 {
8865 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8866 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
8867 params->assocresp_ies_len, NULL,
8868 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8869 {
8870 hddLog(LOGE,
8871 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008872 ret = -EINVAL;
8873 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008874 }
8875
8876 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8877 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8878 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8879 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8880 == eHAL_STATUS_FAILURE)
8881 {
8882 hddLog(LOGE,
8883 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008884 ret = -EINVAL;
8885 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008886 }
8887 }
8888 else
8889 {
8890 hddLog(VOS_TRACE_LEVEL_INFO,
8891 "%s: No Assoc Response IE received in set beacon",
8892 __func__);
8893
8894 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8895 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8896 eANI_BOOLEAN_FALSE) )
8897 {
8898 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008899 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008900 }
8901 }
8902
Jeff Johnsone7245742012-09-05 17:12:55 -07008903done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008904 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308905 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008906}
Jeff Johnson295189b2012-06-20 16:38:30 -07008907
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308908/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008909 * FUNCTION: wlan_hdd_validate_operation_channel
8910 * called by wlan_hdd_cfg80211_start_bss() and
8911 * wlan_hdd_cfg80211_set_channel()
8912 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308913 * channel list.
8914 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008915VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008916{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308917
Jeff Johnson295189b2012-06-20 16:38:30 -07008918 v_U32_t num_ch = 0;
8919 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8920 u32 indx = 0;
8921 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308922 v_U8_t fValidChannel = FALSE, count = 0;
8923 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308924
Jeff Johnson295189b2012-06-20 16:38:30 -07008925 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8926
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308927 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008928 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308929 /* Validate the channel */
8930 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008931 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308932 if ( channel == rfChannels[count].channelNum )
8933 {
8934 fValidChannel = TRUE;
8935 break;
8936 }
8937 }
8938 if (fValidChannel != TRUE)
8939 {
8940 hddLog(VOS_TRACE_LEVEL_ERROR,
8941 "%s: Invalid Channel [%d]", __func__, channel);
8942 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008943 }
8944 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308945 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308947 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8948 valid_ch, &num_ch))
8949 {
8950 hddLog(VOS_TRACE_LEVEL_ERROR,
8951 "%s: failed to get valid channel list", __func__);
8952 return VOS_STATUS_E_FAILURE;
8953 }
8954 for (indx = 0; indx < num_ch; indx++)
8955 {
8956 if (channel == valid_ch[indx])
8957 {
8958 break;
8959 }
8960 }
8961
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308962 if (indx >= num_ch)
8963 {
8964 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8965 {
8966 eCsrBand band;
8967 unsigned int freq;
8968
8969 sme_GetFreqBand(hHal, &band);
8970
8971 if (eCSR_BAND_5G == band)
8972 {
8973#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8974 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8975 {
8976 freq = ieee80211_channel_to_frequency(channel,
8977 IEEE80211_BAND_2GHZ);
8978 }
8979 else
8980 {
8981 freq = ieee80211_channel_to_frequency(channel,
8982 IEEE80211_BAND_5GHZ);
8983 }
8984#else
8985 freq = ieee80211_channel_to_frequency(channel);
8986#endif
8987 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
8988 return VOS_STATUS_SUCCESS;
8989 }
8990 }
8991
8992 hddLog(VOS_TRACE_LEVEL_ERROR,
8993 "%s: Invalid Channel [%d]", __func__, channel);
8994 return VOS_STATUS_E_FAILURE;
8995 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008996 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308997
Jeff Johnson295189b2012-06-20 16:38:30 -07008998 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308999
Jeff Johnson295189b2012-06-20 16:38:30 -07009000}
9001
Viral Modi3a32cc52013-02-08 11:14:52 -08009002/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309003 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009004 * This function is used to set the channel number
9005 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309006static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009007 struct ieee80211_channel *chan,
9008 enum nl80211_channel_type channel_type
9009 )
9010{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309011 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009012 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009013 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009014 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309015 hdd_context_t *pHddCtx;
9016 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009017
9018 ENTER();
9019
9020 if( NULL == dev )
9021 {
9022 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009023 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009024 return -ENODEV;
9025 }
9026 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309027
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309028 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9029 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9030 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009031 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309032 "%s: device_mode = %s (%d) freq = %d", __func__,
9033 hdd_device_modetoString(pAdapter->device_mode),
9034 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309035
9036 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9037 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309038 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009039 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309040 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009041 }
9042
9043 /*
9044 * Do freq to chan conversion
9045 * TODO: for 11a
9046 */
9047
9048 channel = ieee80211_frequency_to_channel(freq);
9049
9050 /* Check freq range */
9051 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9052 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9053 {
9054 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009055 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009056 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9057 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9058 return -EINVAL;
9059 }
9060
9061 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9062
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309063 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9064 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009065 {
9066 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9067 {
9068 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009069 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009070 return -EINVAL;
9071 }
9072 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9073 "%s: set channel to [%d] for device mode =%d",
9074 __func__, channel,pAdapter->device_mode);
9075 }
9076 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009077 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009078 )
9079 {
9080 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9081 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9082 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9083
9084 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9085 {
9086 /* Link is up then return cant set channel*/
9087 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009088 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009089 return -EINVAL;
9090 }
9091
9092 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9093 pHddStaCtx->conn_info.operationChannel = channel;
9094 pRoamProfile->ChannelInfo.ChannelList =
9095 &pHddStaCtx->conn_info.operationChannel;
9096 }
9097 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009098 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009099 )
9100 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309101 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9102 {
9103 if(VOS_STATUS_SUCCESS !=
9104 wlan_hdd_validate_operation_channel(pAdapter,channel))
9105 {
9106 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009107 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309108 return -EINVAL;
9109 }
9110 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9111 }
9112 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009113 {
9114 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9115
9116 /* If auto channel selection is configured as enable/ 1 then ignore
9117 channel set by supplicant
9118 */
9119 if ( cfg_param->apAutoChannelSelection )
9120 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309121 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9122 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009123 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309124 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9125 __func__, hdd_device_modetoString(pAdapter->device_mode),
9126 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009127 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309128 else
9129 {
9130 if(VOS_STATUS_SUCCESS !=
9131 wlan_hdd_validate_operation_channel(pAdapter,channel))
9132 {
9133 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009134 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309135 return -EINVAL;
9136 }
9137 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9138 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009139 }
9140 }
9141 else
9142 {
9143 hddLog(VOS_TRACE_LEVEL_FATAL,
9144 "%s: Invalid device mode failed to set valid channel", __func__);
9145 return -EINVAL;
9146 }
9147 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309148 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009149}
9150
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309151static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9152 struct net_device *dev,
9153 struct ieee80211_channel *chan,
9154 enum nl80211_channel_type channel_type
9155 )
9156{
9157 int ret;
9158
9159 vos_ssr_protect(__func__);
9160 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9161 vos_ssr_unprotect(__func__);
9162
9163 return ret;
9164}
9165
Jeff Johnson295189b2012-06-20 16:38:30 -07009166#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9167static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9168 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009169#else
9170static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9171 struct cfg80211_beacon_data *params,
9172 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309173 enum nl80211_hidden_ssid hidden_ssid,
9174 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009175#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009176{
9177 tsap_Config_t *pConfig;
9178 beacon_data_t *pBeacon = NULL;
9179 struct ieee80211_mgmt *pMgmt_frame;
9180 v_U8_t *pIe=NULL;
9181 v_U16_t capab_info;
9182 eCsrAuthType RSNAuthType;
9183 eCsrEncryptionType RSNEncryptType;
9184 eCsrEncryptionType mcRSNEncryptType;
9185 int status = VOS_STATUS_SUCCESS;
9186 tpWLAN_SAPEventCB pSapEventCallback;
9187 hdd_hostapd_state_t *pHostapdState;
9188 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
9189 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309190 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009191 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309192 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009193 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009194 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309195 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009196 v_BOOL_t MFPCapable = VOS_FALSE;
9197 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309198 v_BOOL_t sapEnable11AC =
9199 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07009200 ENTER();
9201
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309202 iniConfig = pHddCtx->cfg_ini;
9203
Jeff Johnson295189b2012-06-20 16:38:30 -07009204 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9205
9206 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9207
9208 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9209
9210 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9211
9212 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9213
9214 //channel is already set in the set_channel Call back
9215 //pConfig->channel = pCommitConfig->channel;
9216
9217 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309218 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009219 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9220
9221 pConfig->dtim_period = pBeacon->dtim_period;
9222
Arif Hussain6d2a3322013-11-17 19:50:10 -08009223 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009224 pConfig->dtim_period);
9225
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009226 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009227 {
9228 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009229 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309230 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9231 {
9232 tANI_BOOLEAN restartNeeded;
9233 pConfig->ieee80211d = 1;
9234 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9235 sme_setRegInfo(hHal, pConfig->countryCode);
9236 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9237 }
9238 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009239 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009240 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009241 pConfig->ieee80211d = 1;
9242 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9243 sme_setRegInfo(hHal, pConfig->countryCode);
9244 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009245 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009246 else
9247 {
9248 pConfig->ieee80211d = 0;
9249 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309250 /*
9251 * If auto channel is configured i.e. channel is 0,
9252 * so skip channel validation.
9253 */
9254 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9255 {
9256 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9257 {
9258 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009259 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309260 return -EINVAL;
9261 }
9262 }
9263 else
9264 {
9265 if(1 != pHddCtx->is_dynamic_channel_range_set)
9266 {
9267 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9268 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9269 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9270 }
9271 pHddCtx->is_dynamic_channel_range_set = 0;
9272 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009273 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009274 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009275 {
9276 pConfig->ieee80211d = 0;
9277 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309278
9279#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9280 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9281 pConfig->authType = eSAP_OPEN_SYSTEM;
9282 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9283 pConfig->authType = eSAP_SHARED_KEY;
9284 else
9285 pConfig->authType = eSAP_AUTO_SWITCH;
9286#else
9287 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9288 pConfig->authType = eSAP_OPEN_SYSTEM;
9289 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9290 pConfig->authType = eSAP_SHARED_KEY;
9291 else
9292 pConfig->authType = eSAP_AUTO_SWITCH;
9293#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009294
9295 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309296
9297 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009298 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
9299
9300 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9301
9302 /*Set wps station to configured*/
9303 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9304
9305 if(pIe)
9306 {
9307 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9308 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009309 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009310 return -EINVAL;
9311 }
9312 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9313 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009314 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009315 /* Check 15 bit of WPS IE as it contain information for wps state
9316 * WPS state
9317 */
9318 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9319 {
9320 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9321 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9322 {
9323 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9324 }
9325 }
9326 }
9327 else
9328 {
9329 pConfig->wps_state = SAP_WPS_DISABLED;
9330 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309331 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009332
c_hpothufe599e92014-06-16 11:38:55 +05309333 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9334 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9335 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9336 eCSR_ENCRYPT_TYPE_NONE;
9337
Jeff Johnson295189b2012-06-20 16:38:30 -07009338 pConfig->RSNWPAReqIELength = 0;
9339 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309340 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009341 WLAN_EID_RSN);
9342 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309343 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009344 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9345 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9346 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309347 /* The actual processing may eventually be more extensive than
9348 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009349 * by the app.
9350 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309351 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009352 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9353 &RSNEncryptType,
9354 &mcRSNEncryptType,
9355 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009356 &MFPCapable,
9357 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009358 pConfig->pRSNWPAReqIE[1]+2,
9359 pConfig->pRSNWPAReqIE );
9360
9361 if( VOS_STATUS_SUCCESS == status )
9362 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309363 /* Now copy over all the security attributes you have
9364 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009365 * */
9366 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9367 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9368 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9369 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309370 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009371 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009372 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9373 }
9374 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309375
Jeff Johnson295189b2012-06-20 16:38:30 -07009376 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9377 pBeacon->tail, pBeacon->tail_len);
9378
9379 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9380 {
9381 if (pConfig->pRSNWPAReqIE)
9382 {
9383 /*Mixed mode WPA/WPA2*/
9384 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
9385 pConfig->RSNWPAReqIELength += pIe[1] + 2;
9386 }
9387 else
9388 {
9389 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9390 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9391 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309392 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009393 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9394 &RSNEncryptType,
9395 &mcRSNEncryptType,
9396 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009397 &MFPCapable,
9398 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009399 pConfig->pRSNWPAReqIE[1]+2,
9400 pConfig->pRSNWPAReqIE );
9401
9402 if( VOS_STATUS_SUCCESS == status )
9403 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309404 /* Now copy over all the security attributes you have
9405 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009406 * */
9407 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9408 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9409 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9410 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309411 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009412 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009413 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9414 }
9415 }
9416 }
9417
Jeff Johnson4416a782013-03-25 14:17:50 -07009418 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
9419 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9420 return -EINVAL;
9421 }
9422
Jeff Johnson295189b2012-06-20 16:38:30 -07009423 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9424
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009425#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009426 if (params->ssid != NULL)
9427 {
9428 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9429 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9430 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9431 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9432 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009433#else
9434 if (ssid != NULL)
9435 {
9436 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9437 pConfig->SSIDinfo.ssid.length = ssid_len;
9438 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9439 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9440 }
9441#endif
9442
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309443 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009444 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309445
Jeff Johnson295189b2012-06-20 16:38:30 -07009446 /* default value */
9447 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9448 pConfig->num_accept_mac = 0;
9449 pConfig->num_deny_mac = 0;
9450
9451 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9452 pBeacon->tail, pBeacon->tail_len);
9453
9454 /* pIe for black list is following form:
9455 type : 1 byte
9456 length : 1 byte
9457 OUI : 4 bytes
9458 acl type : 1 byte
9459 no of mac addr in black list: 1 byte
9460 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309461 */
9462 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009463 {
9464 pConfig->SapMacaddr_acl = pIe[6];
9465 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009466 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309468 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9469 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009470 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9471 for (i = 0; i < pConfig->num_deny_mac; i++)
9472 {
9473 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9474 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309475 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009476 }
9477 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9478 pBeacon->tail, pBeacon->tail_len);
9479
9480 /* pIe for white list is following form:
9481 type : 1 byte
9482 length : 1 byte
9483 OUI : 4 bytes
9484 acl type : 1 byte
9485 no of mac addr in white list: 1 byte
9486 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309487 */
9488 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009489 {
9490 pConfig->SapMacaddr_acl = pIe[6];
9491 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009492 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009493 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309494 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9495 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009496 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9497 for (i = 0; i < pConfig->num_accept_mac; i++)
9498 {
9499 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9500 acl_entry++;
9501 }
9502 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309503
Jeff Johnson295189b2012-06-20 16:38:30 -07009504 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9505
Jeff Johnsone7245742012-09-05 17:12:55 -07009506#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009507 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309508 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9509 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309510 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9511 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009512 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9513 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309514 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9515 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009516 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309517 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009518 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309519 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009520
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309521 /* If ACS disable and selected channel <= 14
9522 * OR
9523 * ACS enabled and ACS operating band is choosen as 2.4
9524 * AND
9525 * VHT in 2.4G Disabled
9526 * THEN
9527 * Fallback to 11N mode
9528 */
9529 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9530 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309531 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309532 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009533 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309534 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9535 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009536 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9537 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009538 }
9539#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309540
Jeff Johnson295189b2012-06-20 16:38:30 -07009541 // ht_capab is not what the name conveys,this is used for protection bitmap
9542 pConfig->ht_capab =
9543 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9544
9545 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
9546 {
9547 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9548 return -EINVAL;
9549 }
9550
9551 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309552 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009553 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9554 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309555 pConfig->obssProtEnabled =
9556 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009557
Chet Lanctot8cecea22014-02-11 19:09:36 -08009558#ifdef WLAN_FEATURE_11W
9559 pConfig->mfpCapable = MFPCapable;
9560 pConfig->mfpRequired = MFPRequired;
9561 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9562 pConfig->mfpCapable, pConfig->mfpRequired);
9563#endif
9564
Arif Hussain6d2a3322013-11-17 19:50:10 -08009565 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009566 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009567 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9568 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9569 (int)pConfig->channel);
9570 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9571 pConfig->SapHw_mode, pConfig->privacy,
9572 pConfig->authType);
9573 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9574 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9575 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9576 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009577
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309578 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009579 {
9580 //Bss already started. just return.
9581 //TODO Probably it should update some beacon params.
9582 hddLog( LOGE, "Bss Already started...Ignore the request");
9583 EXIT();
9584 return 0;
9585 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309586
Agarwal Ashish51325b52014-06-16 16:50:49 +05309587 if (vos_max_concurrent_connections_reached()) {
9588 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9589 return -EINVAL;
9590 }
9591
Jeff Johnson295189b2012-06-20 16:38:30 -07009592 pConfig->persona = pHostapdAdapter->device_mode;
9593
Peng Xu2446a892014-09-05 17:21:18 +05309594 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9595 if ( NULL != psmeConfig)
9596 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309597 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309598 sme_GetConfigParam(hHal, psmeConfig);
9599 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309600#ifdef WLAN_FEATURE_AP_HT40_24G
9601 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9602 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9603 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9604 {
9605 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9606 sme_UpdateConfig (hHal, psmeConfig);
9607 }
9608#endif
Peng Xu2446a892014-09-05 17:21:18 +05309609 vos_mem_free(psmeConfig);
9610 }
Peng Xuafc34e32014-09-25 13:23:55 +05309611 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309612
Jeff Johnson295189b2012-06-20 16:38:30 -07009613 pSapEventCallback = hdd_hostapd_SAPEventCB;
9614 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9615 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9616 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009617 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009618 return -EINVAL;
9619 }
9620
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309621 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009622 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9623
9624 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309625
Jeff Johnson295189b2012-06-20 16:38:30 -07009626 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309627 {
9628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009629 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009630 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009631 VOS_ASSERT(0);
9632 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309633
Jeff Johnson295189b2012-06-20 16:38:30 -07009634 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309635 /* Initialize WMM configuation */
9636 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309637 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009638
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009639#ifdef WLAN_FEATURE_P2P_DEBUG
9640 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9641 {
9642 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9643 {
9644 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9645 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009646 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009647 }
9648 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9649 {
9650 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9651 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009652 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009653 }
9654 }
9655#endif
9656
Jeff Johnson295189b2012-06-20 16:38:30 -07009657 pHostapdState->bCommit = TRUE;
9658 EXIT();
9659
9660 return 0;
9661}
9662
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009663#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309664static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309665 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009666 struct beacon_parameters *params)
9667{
9668 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309669 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309670 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009671
9672 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309673
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309674 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9675 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9676 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309677 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9678 hdd_device_modetoString(pAdapter->device_mode),
9679 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009680
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309681 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9682 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309683 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009684 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309685 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009686 }
9687
Agarwal Ashish51325b52014-06-16 16:50:49 +05309688 if (vos_max_concurrent_connections_reached()) {
9689 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9690 return -EINVAL;
9691 }
9692
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309693 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009694 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009695 )
9696 {
9697 beacon_data_t *old,*new;
9698
9699 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309700
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309702 {
9703 hddLog(VOS_TRACE_LEVEL_WARN,
9704 FL("already beacon info added to session(%d)"),
9705 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009706 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309707 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009708
9709 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9710
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309711 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009712 {
9713 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009714 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009715 return -EINVAL;
9716 }
9717
9718 pAdapter->sessionCtx.ap.beacon = new;
9719
9720 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9721 }
9722
9723 EXIT();
9724 return status;
9725}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309726
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309727static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9728 struct net_device *dev,
9729 struct beacon_parameters *params)
9730{
9731 int ret;
9732
9733 vos_ssr_protect(__func__);
9734 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
9735 vos_ssr_unprotect(__func__);
9736
9737 return ret;
9738}
9739
9740static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009741 struct net_device *dev,
9742 struct beacon_parameters *params)
9743{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309744 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309745 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9746 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309747 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009748
9749 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309750
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309751 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9752 TRACE_CODE_HDD_CFG80211_SET_BEACON,
9753 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
9754 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9755 __func__, hdd_device_modetoString(pAdapter->device_mode),
9756 pAdapter->device_mode);
9757
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309758 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9759 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309760 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009761 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309762 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009763 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309764
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309765 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009766 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309767 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009768 {
9769 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309770
Jeff Johnson295189b2012-06-20 16:38:30 -07009771 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309772
Jeff Johnson295189b2012-06-20 16:38:30 -07009773 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309774 {
9775 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9776 FL("session(%d) old and new heads points to NULL"),
9777 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009778 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309779 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009780
9781 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9782
9783 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309784 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009785 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009786 return -EINVAL;
9787 }
9788
9789 pAdapter->sessionCtx.ap.beacon = new;
9790
9791 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9792 }
9793
9794 EXIT();
9795 return status;
9796}
9797
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309798static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
9799 struct net_device *dev,
9800 struct beacon_parameters *params)
9801{
9802 int ret;
9803
9804 vos_ssr_protect(__func__);
9805 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
9806 vos_ssr_unprotect(__func__);
9807
9808 return ret;
9809}
9810
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009811#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9812
9813#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309814static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009815 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009816#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309817static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009818 struct net_device *dev)
9819#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009820{
9821 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07009822 hdd_context_t *pHddCtx = NULL;
9823 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309824 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309825 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009826
9827 ENTER();
9828
9829 if (NULL == pAdapter)
9830 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009832 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009833 return -ENODEV;
9834 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009835
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309836 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9837 TRACE_CODE_HDD_CFG80211_STOP_AP,
9838 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309839 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9840 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309841 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009842 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309843 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07009844 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009845
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009846 pScanInfo = &pHddCtx->scan_info;
9847
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309848 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9849 __func__, hdd_device_modetoString(pAdapter->device_mode),
9850 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009851
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309852 ret = wlan_hdd_scan_abort(pAdapter);
9853
Girish Gowli4bf7a632014-06-12 13:42:11 +05309854 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07009855 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9857 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309858
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309859 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07009860 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9862 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08009863
Jeff Johnsone7245742012-09-05 17:12:55 -07009864 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309865 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07009866 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309867 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009868 }
9869
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05309870 /* Delete all associated STAs before stopping AP/P2P GO */
9871 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05309872 hdd_hostapd_stop(dev);
9873
Jeff Johnson295189b2012-06-20 16:38:30 -07009874 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009875 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009876 )
9877 {
9878 beacon_data_t *old;
9879
9880 old = pAdapter->sessionCtx.ap.beacon;
9881
9882 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309883 {
9884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9885 FL("session(%d) beacon data points to NULL"),
9886 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009887 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309888 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009889
Jeff Johnson295189b2012-06-20 16:38:30 -07009890 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009891
9892 mutex_lock(&pHddCtx->sap_lock);
9893 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9894 {
Jeff Johnson4416a782013-03-25 14:17:50 -07009895 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009896 {
9897 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9898
9899 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9900
9901 if (!VOS_IS_STATUS_SUCCESS(status))
9902 {
9903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009904 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009905 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309906 }
9907 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009908 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309909 /* BSS stopped, clear the active sessions for this device mode */
9910 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009911 }
9912 mutex_unlock(&pHddCtx->sap_lock);
9913
9914 if(status != VOS_STATUS_SUCCESS)
9915 {
9916 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009917 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009918 return -EINVAL;
9919 }
9920
Jeff Johnson4416a782013-03-25 14:17:50 -07009921 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009922 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
9923 ==eHAL_STATUS_FAILURE)
9924 {
9925 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009926 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009927 }
9928
Jeff Johnson4416a782013-03-25 14:17:50 -07009929 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009930 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9931 eANI_BOOLEAN_FALSE) )
9932 {
9933 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009934 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009935 }
9936
9937 // Reset WNI_CFG_PROBE_RSP Flags
9938 wlan_hdd_reset_prob_rspies(pAdapter);
9939
9940 pAdapter->sessionCtx.ap.beacon = NULL;
9941 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009942#ifdef WLAN_FEATURE_P2P_DEBUG
9943 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
9944 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
9945 {
9946 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
9947 "GO got removed");
9948 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
9949 }
9950#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009951 }
9952 EXIT();
9953 return status;
9954}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009955
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309956#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9957static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
9958 struct net_device *dev)
9959{
9960 int ret;
9961
9962 vos_ssr_protect(__func__);
9963 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
9964 vos_ssr_unprotect(__func__);
9965
9966 return ret;
9967}
9968#else
9969static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
9970 struct net_device *dev)
9971{
9972 int ret;
9973
9974 vos_ssr_protect(__func__);
9975 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
9976 vos_ssr_unprotect(__func__);
9977
9978 return ret;
9979}
9980#endif
9981
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009982#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
9983
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309984static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309985 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009986 struct cfg80211_ap_settings *params)
9987{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309988 hdd_adapter_t *pAdapter;
9989 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309990 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009991
9992 ENTER();
9993
Girish Gowlib143d7a2015-02-18 19:39:55 +05309994 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009995 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05309997 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309998 return -ENODEV;
9999 }
10000
10001 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10002 if (NULL == pAdapter)
10003 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010005 "%s: HDD adapter is Null", __func__);
10006 return -ENODEV;
10007 }
10008
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010009 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10010 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
10011 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010012 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
10013 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010015 "%s: HDD adapter magic is invalid", __func__);
10016 return -ENODEV;
10017 }
10018
10019 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010020 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010021 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010022 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010023 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010024 }
10025
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010026 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10027 __func__, hdd_device_modetoString(pAdapter->device_mode),
10028 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010029
10030 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010031 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010032 )
10033 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010034 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010035
10036 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010037
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010038 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010039 {
10040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10041 FL("already beacon info added to session(%d)"),
10042 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010043 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010044 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010045
Girish Gowlib143d7a2015-02-18 19:39:55 +053010046#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10047 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10048 &new,
10049 &params->beacon);
10050#else
10051 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10052 &new,
10053 &params->beacon,
10054 params->dtim_period);
10055#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010056
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010057 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010058 {
10059 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010060 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010061 return -EINVAL;
10062 }
10063 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010064#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010065 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10066#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10067 params->channel, params->channel_type);
10068#else
10069 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10070#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010071#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010072 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010073 params->ssid_len, params->hidden_ssid,
10074 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010075 }
10076
10077 EXIT();
10078 return status;
10079}
10080
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010081static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10082 struct net_device *dev,
10083 struct cfg80211_ap_settings *params)
10084{
10085 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010086
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010087 vos_ssr_protect(__func__);
10088 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10089 vos_ssr_unprotect(__func__);
10090
10091 return ret;
10092}
10093
10094static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010095 struct net_device *dev,
10096 struct cfg80211_beacon_data *params)
10097{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010098 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010099 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010100 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010101
10102 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010103
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010104 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10105 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10106 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010107 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010108 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010109
10110 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10111 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010112 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010113 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010114 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010115 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010116
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010117 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010118 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010119 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010120 {
10121 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010122
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010123 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010124
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010125 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010126 {
10127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10128 FL("session(%d) beacon data points to NULL"),
10129 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010130 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010131 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010132
10133 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10134
10135 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010136 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010137 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010138 return -EINVAL;
10139 }
10140
10141 pAdapter->sessionCtx.ap.beacon = new;
10142
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010143 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10144 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010145 }
10146
10147 EXIT();
10148 return status;
10149}
10150
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010151static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10152 struct net_device *dev,
10153 struct cfg80211_beacon_data *params)
10154{
10155 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010156
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010157 vos_ssr_protect(__func__);
10158 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10159 vos_ssr_unprotect(__func__);
10160
10161 return ret;
10162}
10163
10164#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010165
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010166static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010167 struct net_device *dev,
10168 struct bss_parameters *params)
10169{
10170 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010171 hdd_context_t *pHddCtx;
10172 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010173
10174 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010175
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010176 if (NULL == pAdapter)
10177 {
10178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10179 "%s: HDD adapter is Null", __func__);
10180 return -ENODEV;
10181 }
10182 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010183 ret = wlan_hdd_validate_context(pHddCtx);
10184 if (0 != ret)
10185 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010186 return ret;
10187 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010188 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10189 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10190 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010191 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10192 __func__, hdd_device_modetoString(pAdapter->device_mode),
10193 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010194
10195 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010196 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010197 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010198 {
10199 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10200 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010201 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010202 {
10203 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010204 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010205 }
10206
10207 EXIT();
10208 return 0;
10209}
10210
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010211static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10212 struct net_device *dev,
10213 struct bss_parameters *params)
10214{
10215 int ret;
10216
10217 vos_ssr_protect(__func__);
10218 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10219 vos_ssr_unprotect(__func__);
10220
10221 return ret;
10222}
Kiet Lam10841362013-11-01 11:36:50 +053010223/* FUNCTION: wlan_hdd_change_country_code_cd
10224* to wait for contry code completion
10225*/
10226void* wlan_hdd_change_country_code_cb(void *pAdapter)
10227{
10228 hdd_adapter_t *call_back_pAdapter = pAdapter;
10229 complete(&call_back_pAdapter->change_country_code);
10230 return NULL;
10231}
10232
Jeff Johnson295189b2012-06-20 16:38:30 -070010233/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010234 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010235 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10236 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010237int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010238 struct net_device *ndev,
10239 enum nl80211_iftype type,
10240 u32 *flags,
10241 struct vif_params *params
10242 )
10243{
10244 struct wireless_dev *wdev;
10245 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010246 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010247 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010248 tCsrRoamProfile *pRoamProfile = NULL;
10249 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010250 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010251 eMib_dot11DesiredBssType connectedBssType;
10252 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010253 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010254
10255 ENTER();
10256
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010257 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010258 {
10259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10260 "%s: Adapter context is null", __func__);
10261 return VOS_STATUS_E_FAILURE;
10262 }
10263
10264 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10265 if (!pHddCtx)
10266 {
10267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10268 "%s: HDD context is null", __func__);
10269 return VOS_STATUS_E_FAILURE;
10270 }
10271
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010272 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10273 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10274 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010275 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010276 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010277 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010278 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010279 }
10280
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010281 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10282 __func__, hdd_device_modetoString(pAdapter->device_mode),
10283 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010284
Agarwal Ashish51325b52014-06-16 16:50:49 +053010285 if (vos_max_concurrent_connections_reached()) {
10286 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10287 return -EINVAL;
10288 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010289 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010290 wdev = ndev->ieee80211_ptr;
10291
10292#ifdef WLAN_BTAMP_FEATURE
10293 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10294 (NL80211_IFTYPE_ADHOC == type)||
10295 (NL80211_IFTYPE_AP == type)||
10296 (NL80211_IFTYPE_P2P_GO == type))
10297 {
10298 pHddCtx->isAmpAllowed = VOS_FALSE;
10299 // stop AMP traffic
10300 status = WLANBAP_StopAmp();
10301 if(VOS_STATUS_SUCCESS != status )
10302 {
10303 pHddCtx->isAmpAllowed = VOS_TRUE;
10304 hddLog(VOS_TRACE_LEVEL_FATAL,
10305 "%s: Failed to stop AMP", __func__);
10306 return -EINVAL;
10307 }
10308 }
10309#endif //WLAN_BTAMP_FEATURE
10310 /* Reset the current device mode bit mask*/
10311 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10312
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010313 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10314 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10315 (type == NL80211_IFTYPE_P2P_GO)))
10316 {
10317 /* Notify Mode change in case of concurrency.
10318 * Below function invokes TDLS teardown Functionality Since TDLS is
10319 * not Supported in case of concurrency i.e Once P2P session
10320 * is detected disable offchannel and teardown TDLS links
10321 */
10322 hddLog(LOG1,
10323 FL("Device mode = %d Interface type = %d"),
10324 pAdapter->device_mode, type);
10325 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10326 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010327
Jeff Johnson295189b2012-06-20 16:38:30 -070010328 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010329 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010330 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010331 )
10332 {
10333 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010334 if (!pWextState)
10335 {
10336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10337 "%s: pWextState is null", __func__);
10338 return VOS_STATUS_E_FAILURE;
10339 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010340 pRoamProfile = &pWextState->roamProfile;
10341 LastBSSType = pRoamProfile->BSSType;
10342
10343 switch (type)
10344 {
10345 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010346 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010347 hddLog(VOS_TRACE_LEVEL_INFO,
10348 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10349 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010350#ifdef WLAN_FEATURE_11AC
10351 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10352 {
10353 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10354 }
10355#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010356 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010357 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010358 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010359 //Check for sub-string p2p to confirm its a p2p interface
10360 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010361 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010362#ifdef FEATURE_WLAN_TDLS
10363 mutex_lock(&pHddCtx->tdls_lock);
10364 wlan_hdd_tdls_exit(pAdapter, TRUE);
10365 mutex_unlock(&pHddCtx->tdls_lock);
10366#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010367 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10368 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10369 }
10370 else
10371 {
10372 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010373 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010374 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010375 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010376
Jeff Johnson295189b2012-06-20 16:38:30 -070010377 case NL80211_IFTYPE_ADHOC:
10378 hddLog(VOS_TRACE_LEVEL_INFO,
10379 "%s: setting interface Type to ADHOC", __func__);
10380 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10381 pRoamProfile->phyMode =
10382 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010383 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010384 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010385 hdd_set_ibss_ops( pAdapter );
10386 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010387
10388 status = hdd_sta_id_hash_attach(pAdapter);
10389 if (VOS_STATUS_SUCCESS != status) {
10390 hddLog(VOS_TRACE_LEVEL_ERROR,
10391 FL("Failed to initialize hash for IBSS"));
10392 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010393 break;
10394
10395 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010396 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010397 {
10398 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10399 "%s: setting interface Type to %s", __func__,
10400 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10401
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010402 //Cancel any remain on channel for GO mode
10403 if (NL80211_IFTYPE_P2P_GO == type)
10404 {
10405 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10406 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010407 if (NL80211_IFTYPE_AP == type)
10408 {
10409 /* As Loading WLAN Driver one interface being created for p2p device
10410 * address. This will take one HW STA and the max number of clients
10411 * that can connect to softAP will be reduced by one. so while changing
10412 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10413 * interface as it is not required in SoftAP mode.
10414 */
10415
10416 // Get P2P Adapter
10417 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10418
10419 if (pP2pAdapter)
10420 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010421 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010422 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010423 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10424 }
10425 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010426 //Disable IMPS & BMPS for SAP/GO
10427 if(VOS_STATUS_E_FAILURE ==
10428 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10429 {
10430 //Fail to Exit BMPS
10431 VOS_ASSERT(0);
10432 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010433
10434 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10435
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010436#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010437
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010438 /* A Mutex Lock is introduced while changing the mode to
10439 * protect the concurrent access for the Adapters by TDLS
10440 * module.
10441 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010442 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010443#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010444 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010445 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010446 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010447 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10448 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010449#ifdef FEATURE_WLAN_TDLS
10450 mutex_unlock(&pHddCtx->tdls_lock);
10451#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010452 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10453 (pConfig->apRandomBssidEnabled))
10454 {
10455 /* To meet Android requirements create a randomized
10456 MAC address of the form 02:1A:11:Fx:xx:xx */
10457 get_random_bytes(&ndev->dev_addr[3], 3);
10458 ndev->dev_addr[0] = 0x02;
10459 ndev->dev_addr[1] = 0x1A;
10460 ndev->dev_addr[2] = 0x11;
10461 ndev->dev_addr[3] |= 0xF0;
10462 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10463 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010464 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10465 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010466 }
10467
Jeff Johnson295189b2012-06-20 16:38:30 -070010468 hdd_set_ap_ops( pAdapter->dev );
10469
Kiet Lam10841362013-11-01 11:36:50 +053010470 /* This is for only SAP mode where users can
10471 * control country through ini.
10472 * P2P GO follows station country code
10473 * acquired during the STA scanning. */
10474 if((NL80211_IFTYPE_AP == type) &&
10475 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10476 {
10477 int status = 0;
10478 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10479 "%s: setting country code from INI ", __func__);
10480 init_completion(&pAdapter->change_country_code);
10481 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10482 (void *)(tSmeChangeCountryCallback)
10483 wlan_hdd_change_country_code_cb,
10484 pConfig->apCntryCode, pAdapter,
10485 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010486 eSIR_FALSE,
10487 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010488 if (eHAL_STATUS_SUCCESS == status)
10489 {
10490 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010491 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010492 &pAdapter->change_country_code,
10493 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010494 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010495 {
10496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010497 FL("SME Timed out while setting country code %ld"),
10498 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010499
10500 if (pHddCtx->isLogpInProgress)
10501 {
10502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10503 "%s: LOGP in Progress. Ignore!!!", __func__);
10504 return -EAGAIN;
10505 }
Kiet Lam10841362013-11-01 11:36:50 +053010506 }
10507 }
10508 else
10509 {
10510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010511 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010512 return -EINVAL;
10513 }
10514 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010515 status = hdd_init_ap_mode(pAdapter);
10516 if(status != VOS_STATUS_SUCCESS)
10517 {
10518 hddLog(VOS_TRACE_LEVEL_FATAL,
10519 "%s: Error initializing the ap mode", __func__);
10520 return -EINVAL;
10521 }
10522 hdd_set_conparam(1);
10523
Nirav Shah7e3c8132015-06-22 23:51:42 +053010524 status = hdd_sta_id_hash_attach(pAdapter);
10525 if (VOS_STATUS_SUCCESS != status)
10526 {
10527 hddLog(VOS_TRACE_LEVEL_ERROR,
10528 FL("Failed to initialize hash for AP"));
10529 return -EINVAL;
10530 }
10531
Jeff Johnson295189b2012-06-20 16:38:30 -070010532 /*interface type changed update in wiphy structure*/
10533 if(wdev)
10534 {
10535 wdev->iftype = type;
10536 pHddCtx->change_iface = type;
10537 }
10538 else
10539 {
10540 hddLog(VOS_TRACE_LEVEL_ERROR,
10541 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10542 return -EINVAL;
10543 }
10544 goto done;
10545 }
10546
10547 default:
10548 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10549 __func__);
10550 return -EOPNOTSUPP;
10551 }
10552 }
10553 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010554 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010555 )
10556 {
10557 switch(type)
10558 {
10559 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010560 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010561 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010562
10563 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010564#ifdef FEATURE_WLAN_TDLS
10565
10566 /* A Mutex Lock is introduced while changing the mode to
10567 * protect the concurrent access for the Adapters by TDLS
10568 * module.
10569 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010570 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010571#endif
c_hpothu002231a2015-02-05 14:58:51 +053010572 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010573 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010574 //Check for sub-string p2p to confirm its a p2p interface
10575 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010576 {
10577 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10578 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10579 }
10580 else
10581 {
10582 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010583 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010584 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010585 hdd_set_conparam(0);
10586 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010587 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10588 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010589#ifdef FEATURE_WLAN_TDLS
10590 mutex_unlock(&pHddCtx->tdls_lock);
10591#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010592 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010593 if( VOS_STATUS_SUCCESS != status )
10594 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010595 /* In case of JB, for P2P-GO, only change interface will be called,
10596 * This is the right place to enable back bmps_imps()
10597 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010598 if (pHddCtx->hdd_wlan_suspended)
10599 {
10600 hdd_set_pwrparams(pHddCtx);
10601 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010602 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010603 goto done;
10604 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010605 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010606 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010607 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10608 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010609 goto done;
10610 default:
10611 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10612 __func__);
10613 return -EOPNOTSUPP;
10614
10615 }
10616
10617 }
10618 else
10619 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010620 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10621 __func__, hdd_device_modetoString(pAdapter->device_mode),
10622 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010623 return -EOPNOTSUPP;
10624 }
10625
10626
10627 if(pRoamProfile)
10628 {
10629 if ( LastBSSType != pRoamProfile->BSSType )
10630 {
10631 /*interface type changed update in wiphy structure*/
10632 wdev->iftype = type;
10633
10634 /*the BSS mode changed, We need to issue disconnect
10635 if connected or in IBSS disconnect state*/
10636 if ( hdd_connGetConnectedBssType(
10637 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10638 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10639 {
10640 /*need to issue a disconnect to CSR.*/
10641 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10642 if( eHAL_STATUS_SUCCESS ==
10643 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10644 pAdapter->sessionId,
10645 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10646 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010647 ret = wait_for_completion_interruptible_timeout(
10648 &pAdapter->disconnect_comp_var,
10649 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10650 if (ret <= 0)
10651 {
10652 hddLog(VOS_TRACE_LEVEL_ERROR,
10653 FL("wait on disconnect_comp_var failed %ld"), ret);
10654 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010655 }
10656 }
10657 }
10658 }
10659
10660done:
10661 /*set bitmask based on updated value*/
10662 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010663
10664 /* Only STA mode support TM now
10665 * all other mode, TM feature should be disabled */
10666 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10667 (~VOS_STA & pHddCtx->concurrency_mode) )
10668 {
10669 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10670 }
10671
Jeff Johnson295189b2012-06-20 16:38:30 -070010672#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010673 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010674 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010675 {
10676 //we are ok to do AMP
10677 pHddCtx->isAmpAllowed = VOS_TRUE;
10678 }
10679#endif //WLAN_BTAMP_FEATURE
10680 EXIT();
10681 return 0;
10682}
10683
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010684/*
10685 * FUNCTION: wlan_hdd_cfg80211_change_iface
10686 * wrapper function to protect the actual implementation from SSR.
10687 */
10688int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10689 struct net_device *ndev,
10690 enum nl80211_iftype type,
10691 u32 *flags,
10692 struct vif_params *params
10693 )
10694{
10695 int ret;
10696
10697 vos_ssr_protect(__func__);
10698 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10699 vos_ssr_unprotect(__func__);
10700
10701 return ret;
10702}
10703
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010704#ifdef FEATURE_WLAN_TDLS
10705static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010706 struct net_device *dev,
10707#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10708 const u8 *mac,
10709#else
10710 u8 *mac,
10711#endif
10712 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010713{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010714 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010715 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010716 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010717 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010718 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010719 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010720
10721 ENTER();
10722
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010723 if (!dev) {
10724 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10725 return -EINVAL;
10726 }
10727
10728 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10729 if (!pAdapter) {
10730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
10731 return -EINVAL;
10732 }
10733
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010734 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010735 {
10736 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10737 "Invalid arguments");
10738 return -EINVAL;
10739 }
Hoonki Lee27511902013-03-14 18:19:06 -070010740
10741 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
10742 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
10743 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070010745 "%s: TDLS mode is disabled OR not enabled in FW."
10746 MAC_ADDRESS_STR " Request declined.",
10747 __func__, MAC_ADDR_ARRAY(mac));
10748 return -ENOTSUPP;
10749 }
10750
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010751 if (pHddCtx->isLogpInProgress)
10752 {
10753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10754 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053010755 wlan_hdd_tdls_set_link_status(pAdapter,
10756 mac,
10757 eTDLS_LINK_IDLE,
10758 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010759 return -EBUSY;
10760 }
10761
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010762 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053010763 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010764
10765 if ( NULL == pTdlsPeer ) {
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 " (update %d) not exist. return invalid",
10768 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010769 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010770 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010771 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010772
10773 /* in add station, we accept existing valid staId if there is */
10774 if ((0 == update) &&
10775 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
10776 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010777 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010778 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010779 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010780 " link_status %d. staId %d. add station ignored.",
10781 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010782 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010783 return 0;
10784 }
10785 /* in change station, we accept only when staId is valid */
10786 if ((1 == update) &&
10787 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
10788 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
10789 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010790 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010792 "%s: " MAC_ADDRESS_STR
10793 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010794 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
10795 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
10796 mutex_unlock(&pHddCtx->tdls_lock);
10797 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010798 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010799 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010800
10801 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053010802 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010803 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10805 "%s: " MAC_ADDRESS_STR
10806 " TDLS setup is ongoing. Request declined.",
10807 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070010808 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010809 }
10810
10811 /* first to check if we reached to maximum supported TDLS peer.
10812 TODO: for now, return -EPERM looks working fine,
10813 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010814 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
10815 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010816 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010817 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10818 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010819 " TDLS Max peer already connected. Request declined."
10820 " Num of peers (%d), Max allowed (%d).",
10821 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
10822 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010823 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010824 }
10825 else
10826 {
10827 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010828 mutex_lock(&pHddCtx->tdls_lock);
10829 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010830 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010831 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010832 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10834 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
10835 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010836 return -EPERM;
10837 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010838 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010839 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010840 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053010841 wlan_hdd_tdls_set_link_status(pAdapter,
10842 mac,
10843 eTDLS_LINK_CONNECTING,
10844 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010845
Jeff Johnsond75fe012013-04-06 10:53:06 -070010846 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010847 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010848 {
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 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010851 if(StaParams->htcap_present)
10852 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010854 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010856 "ht_capa->extended_capabilities: %0x",
10857 StaParams->HTCap.extendedHtCapInfo);
10858 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010860 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010862 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010863 if(StaParams->vhtcap_present)
10864 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010865 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010866 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
10867 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
10868 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
10869 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010870 {
10871 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010873 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010875 "[%d]: %x ", i, StaParams->supported_rates[i]);
10876 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070010877 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010878 else if ((1 == update) && (NULL == StaParams))
10879 {
10880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10881 "%s : update is true, but staParams is NULL. Error!", __func__);
10882 return -EPERM;
10883 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010884
10885 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
10886
10887 if (!update)
10888 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010889 /*Before adding sta make sure that device exited from BMPS*/
10890 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
10891 {
10892 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10893 "%s: Adding tdls peer sta. Disable BMPS", __func__);
10894 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10895 if (status != VOS_STATUS_SUCCESS) {
10896 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
10897 }
10898 }
10899
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010900 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010901 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010902 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010903 hddLog(VOS_TRACE_LEVEL_ERROR,
10904 FL("Failed to add TDLS peer STA. Enable Bmps"));
10905 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010906 return -EPERM;
10907 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010908 }
10909 else
10910 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010911 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010912 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010913 if (ret != eHAL_STATUS_SUCCESS) {
10914 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
10915 return -EPERM;
10916 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010917 }
10918
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010919 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010920 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
10921
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053010922 mutex_lock(&pHddCtx->tdls_lock);
10923 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
10924
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010925 if ((pTdlsPeer != NULL) &&
10926 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010927 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010928 hddLog(VOS_TRACE_LEVEL_ERROR,
10929 FL("peer link status %u"), pTdlsPeer->link_status);
10930 mutex_unlock(&pHddCtx->tdls_lock);
10931 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010932 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053010933 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010934
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010935 if (ret <= 0)
10936 {
10937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10938 "%s: timeout waiting for tdls add station indication %ld",
10939 __func__, ret);
10940 goto error;
10941 }
10942
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010943 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
10944 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010946 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010947 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010948 }
10949
10950 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070010951
10952error:
Atul Mittal115287b2014-07-08 13:26:33 +053010953 wlan_hdd_tdls_set_link_status(pAdapter,
10954 mac,
10955 eTDLS_LINK_IDLE,
10956 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010957 return -EPERM;
10958
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010959}
10960#endif
10961
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010962static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010963 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010964#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10965 const u8 *mac,
10966#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010967 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010968#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010969 struct station_parameters *params)
10970{
10971 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010972 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010973 hdd_context_t *pHddCtx;
10974 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010975 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010976 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010977#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010978 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010979 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010980 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053010981 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010982#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010983
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010984 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010985
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010986 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010987 if ((NULL == pAdapter))
10988 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010990 "invalid adapter ");
10991 return -EINVAL;
10992 }
10993
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010994 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10995 TRACE_CODE_HDD_CHANGE_STATION,
10996 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053010997 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010998
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010999 ret = wlan_hdd_validate_context(pHddCtx);
11000 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053011001 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011002 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011003 }
11004
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011005 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11006
11007 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011008 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11010 "invalid HDD station context");
11011 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011012 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011013 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
11014
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011015 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11016 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070011017 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011018 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070011019 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011020 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070011021 WLANTL_STA_AUTHENTICATED);
11022
Gopichand Nakkala29149562013-05-10 21:43:41 +053011023 if (status != VOS_STATUS_SUCCESS)
11024 {
11025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11026 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11027 return -EINVAL;
11028 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011029 }
11030 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011031 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11032 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011033#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011034 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11035 StaParams.capability = params->capability;
11036 StaParams.uapsd_queues = params->uapsd_queues;
11037 StaParams.max_sp = params->max_sp;
11038
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011039 /* Convert (first channel , number of channels) tuple to
11040 * the total list of channels. This goes with the assumption
11041 * that if the first channel is < 14, then the next channels
11042 * are an incremental of 1 else an incremental of 4 till the number
11043 * of channels.
11044 */
11045 if (0 != params->supported_channels_len) {
11046 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11047 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11048 {
11049 int wifi_chan_index;
11050 StaParams.supported_channels[j] = params->supported_channels[i];
11051 wifi_chan_index =
11052 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11053 no_of_channels = params->supported_channels[i+1];
11054 for(k=1; k <= no_of_channels; k++)
11055 {
11056 StaParams.supported_channels[j+1] =
11057 StaParams.supported_channels[j] + wifi_chan_index;
11058 j+=1;
11059 }
11060 }
11061 StaParams.supported_channels_len = j;
11062 }
11063 vos_mem_copy(StaParams.supported_oper_classes,
11064 params->supported_oper_classes,
11065 params->supported_oper_classes_len);
11066 StaParams.supported_oper_classes_len =
11067 params->supported_oper_classes_len;
11068
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011069 if (0 != params->ext_capab_len)
11070 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
11071 sizeof(StaParams.extn_capability));
11072
11073 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011074 {
11075 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011076 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011077 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011078
11079 StaParams.supported_rates_len = params->supported_rates_len;
11080
11081 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11082 * The supported_rates array , for all the structures propogating till Add Sta
11083 * to the firmware has to be modified , if the supplicant (ieee80211) is
11084 * modified to send more rates.
11085 */
11086
11087 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11088 */
11089 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11090 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11091
11092 if (0 != StaParams.supported_rates_len) {
11093 int i = 0;
11094 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11095 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011097 "Supported Rates with Length %d", StaParams.supported_rates_len);
11098 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011100 "[%d]: %0x", i, StaParams.supported_rates[i]);
11101 }
11102
11103 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011104 {
11105 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011106 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011107 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011108
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011109 if (0 != params->ext_capab_len ) {
11110 /*Define A Macro : TODO Sunil*/
11111 if ((1<<4) & StaParams.extn_capability[3]) {
11112 isBufSta = 1;
11113 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011114 /* TDLS Channel Switching Support */
11115 if ((1<<6) & StaParams.extn_capability[3]) {
11116 isOffChannelSupported = 1;
11117 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011118 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011119
11120 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011121 (params->ht_capa || params->vht_capa ||
11122 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011123 /* TDLS Peer is WME/QoS capable */
11124 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011125
11126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11127 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11128 __func__, isQosWmmSta, StaParams.htcap_present);
11129
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011130 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11131 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011132 isOffChannelSupported,
11133 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011134
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011135 if (VOS_STATUS_SUCCESS != status) {
11136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11137 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11138 return -EINVAL;
11139 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011140 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11141
11142 if (VOS_STATUS_SUCCESS != status) {
11143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11144 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11145 return -EINVAL;
11146 }
11147 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011148#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011149 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011150 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 return status;
11152}
11153
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011154#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11155static int wlan_hdd_change_station(struct wiphy *wiphy,
11156 struct net_device *dev,
11157 const u8 *mac,
11158 struct station_parameters *params)
11159#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011160static int wlan_hdd_change_station(struct wiphy *wiphy,
11161 struct net_device *dev,
11162 u8 *mac,
11163 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011164#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011165{
11166 int ret;
11167
11168 vos_ssr_protect(__func__);
11169 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11170 vos_ssr_unprotect(__func__);
11171
11172 return ret;
11173}
11174
Jeff Johnson295189b2012-06-20 16:38:30 -070011175/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011176 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011177 * This function is used to initialize the key information
11178 */
11179#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011180static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011181 struct net_device *ndev,
11182 u8 key_index, bool pairwise,
11183 const u8 *mac_addr,
11184 struct key_params *params
11185 )
11186#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011187static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011188 struct net_device *ndev,
11189 u8 key_index, const u8 *mac_addr,
11190 struct key_params *params
11191 )
11192#endif
11193{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011194 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011195 tCsrRoamSetKey setKey;
11196 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011197 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011198 v_U32_t roamId= 0xFF;
11199 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011200 hdd_hostapd_state_t *pHostapdState;
11201 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011202 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011203 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011204
11205 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011206
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011207 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11208 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11209 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011210 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11211 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011212 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011213 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011214 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011215 }
11216
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011217 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11218 __func__, hdd_device_modetoString(pAdapter->device_mode),
11219 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011220
11221 if (CSR_MAX_NUM_KEY <= key_index)
11222 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011223 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011224 key_index);
11225
11226 return -EINVAL;
11227 }
11228
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011229 if (CSR_MAX_KEY_LEN < params->key_len)
11230 {
11231 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11232 params->key_len);
11233
11234 return -EINVAL;
11235 }
11236
11237 hddLog(VOS_TRACE_LEVEL_INFO,
11238 "%s: called with key index = %d & key length %d",
11239 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011240
11241 /*extract key idx, key len and key*/
11242 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11243 setKey.keyId = key_index;
11244 setKey.keyLength = params->key_len;
11245 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11246
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011247 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011248 {
11249 case WLAN_CIPHER_SUITE_WEP40:
11250 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11251 break;
11252
11253 case WLAN_CIPHER_SUITE_WEP104:
11254 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11255 break;
11256
11257 case WLAN_CIPHER_SUITE_TKIP:
11258 {
11259 u8 *pKey = &setKey.Key[0];
11260 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11261
11262 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11263
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011264 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011265
11266 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011267 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011268 |--------------|----------|----------|
11269 <---16bytes---><--8bytes--><--8bytes-->
11270
11271 */
11272 /*Sme expects the 32 bytes key to be in the below order
11273
11274 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011275 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011276 |--------------|----------|----------|
11277 <---16bytes---><--8bytes--><--8bytes-->
11278 */
11279 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011280 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011281
11282 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011283 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011284
11285 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011286 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011287
11288
11289 break;
11290 }
11291
11292 case WLAN_CIPHER_SUITE_CCMP:
11293 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11294 break;
11295
11296#ifdef FEATURE_WLAN_WAPI
11297 case WLAN_CIPHER_SUITE_SMS4:
11298 {
11299 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11300 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11301 params->key, params->key_len);
11302 return 0;
11303 }
11304#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011305
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011306#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011307 case WLAN_CIPHER_SUITE_KRK:
11308 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11309 break;
11310#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011311
11312#ifdef WLAN_FEATURE_11W
11313 case WLAN_CIPHER_SUITE_AES_CMAC:
11314 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011315 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011316#endif
11317
Jeff Johnson295189b2012-06-20 16:38:30 -070011318 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011319 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011320 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011321 status = -EOPNOTSUPP;
11322 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011323 }
11324
11325 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11326 __func__, setKey.encType);
11327
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011328 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011329#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11330 (!pairwise)
11331#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011332 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011333#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011334 )
11335 {
11336 /* set group key*/
11337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11338 "%s- %d: setting Broadcast key",
11339 __func__, __LINE__);
11340 setKey.keyDirection = eSIR_RX_ONLY;
11341 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11342 }
11343 else
11344 {
11345 /* set pairwise key*/
11346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11347 "%s- %d: setting pairwise key",
11348 __func__, __LINE__);
11349 setKey.keyDirection = eSIR_TX_RX;
11350 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11351 }
11352 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11353 {
11354 setKey.keyDirection = eSIR_TX_RX;
11355 /*Set the group key*/
11356 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11357 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011358
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011359 if ( 0 != status )
11360 {
11361 hddLog(VOS_TRACE_LEVEL_ERROR,
11362 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011363 status = -EINVAL;
11364 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011365 }
11366 /*Save the keys here and call sme_RoamSetKey for setting
11367 the PTK after peer joins the IBSS network*/
11368 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11369 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011370 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011371 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011372 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11373 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11374 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011375 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011376 if( pHostapdState->bssState == BSS_START )
11377 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011378 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11379 vos_status = wlan_hdd_check_ula_done(pAdapter);
11380
11381 if ( vos_status != VOS_STATUS_SUCCESS )
11382 {
11383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11384 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11385 __LINE__, vos_status );
11386
11387 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11388
11389 status = -EINVAL;
11390 goto end;
11391 }
11392
Jeff Johnson295189b2012-06-20 16:38:30 -070011393 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11394
11395 if ( status != eHAL_STATUS_SUCCESS )
11396 {
11397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11398 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11399 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011400 status = -EINVAL;
11401 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011402 }
11403 }
11404
11405 /* Saving WEP keys */
11406 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11407 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11408 {
11409 //Save the wep key in ap context. Issue setkey after the BSS is started.
11410 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11411 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11412 }
11413 else
11414 {
11415 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011416 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011417 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11418 }
11419 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011420 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11421 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011422 {
11423 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11424 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11425
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011426#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11427 if (!pairwise)
11428#else
11429 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11430#endif
11431 {
11432 /* set group key*/
11433 if (pHddStaCtx->roam_info.deferKeyComplete)
11434 {
11435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11436 "%s- %d: Perform Set key Complete",
11437 __func__, __LINE__);
11438 hdd_PerformRoamSetKeyComplete(pAdapter);
11439 }
11440 }
11441
Jeff Johnson295189b2012-06-20 16:38:30 -070011442 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11443
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011444 pWextState->roamProfile.Keys.defaultIndex = key_index;
11445
11446
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011447 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011448 params->key, params->key_len);
11449
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011450
Jeff Johnson295189b2012-06-20 16:38:30 -070011451 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11452
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011453 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011454 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011455 __func__, setKey.peerMac[0], setKey.peerMac[1],
11456 setKey.peerMac[2], setKey.peerMac[3],
11457 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011458 setKey.keyDirection);
11459
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011460 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011461
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011462 if ( vos_status != VOS_STATUS_SUCCESS )
11463 {
11464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011465 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11466 __LINE__, vos_status );
11467
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011468 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011469
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011470 status = -EINVAL;
11471 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011472
11473 }
11474
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011475#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011476 /* The supplicant may attempt to set the PTK once pre-authentication
11477 is done. Save the key in the UMAC and include it in the ADD BSS
11478 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011479 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011480 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011481 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011482 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11483 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011484 status = 0;
11485 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011486 }
11487 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11488 {
11489 hddLog(VOS_TRACE_LEVEL_ERROR,
11490 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011491 status = -EINVAL;
11492 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011493 }
11494#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011495
11496 /* issue set key request to SME*/
11497 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11498 pAdapter->sessionId, &setKey, &roamId );
11499
11500 if ( 0 != status )
11501 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011502 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011503 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11504 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011505 status = -EINVAL;
11506 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011507 }
11508
11509
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011510 /* in case of IBSS as there was no information available about WEP keys during
11511 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011512 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011513 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11514 !( ( IW_AUTH_KEY_MGMT_802_1X
11515 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011516 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11517 )
11518 &&
11519 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11520 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11521 )
11522 )
11523 {
11524 setKey.keyDirection = eSIR_RX_ONLY;
11525 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11526
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011527 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011528 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011529 __func__, setKey.peerMac[0], setKey.peerMac[1],
11530 setKey.peerMac[2], setKey.peerMac[3],
11531 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011532 setKey.keyDirection);
11533
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011534 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011535 pAdapter->sessionId, &setKey, &roamId );
11536
11537 if ( 0 != status )
11538 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011539 hddLog(VOS_TRACE_LEVEL_ERROR,
11540 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011541 __func__, status);
11542 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011543 status = -EINVAL;
11544 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011545 }
11546 }
11547 }
11548
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011549end:
11550 /* Need to clear any trace of key value in the memory.
11551 * Thus zero out the memory even though it is local
11552 * variable.
11553 */
11554 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011555 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011556 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011557}
11558
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011559#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11560static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11561 struct net_device *ndev,
11562 u8 key_index, bool pairwise,
11563 const u8 *mac_addr,
11564 struct key_params *params
11565 )
11566#else
11567static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11568 struct net_device *ndev,
11569 u8 key_index, const u8 *mac_addr,
11570 struct key_params *params
11571 )
11572#endif
11573{
11574 int ret;
11575 vos_ssr_protect(__func__);
11576#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11577 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11578 mac_addr, params);
11579#else
11580 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11581 params);
11582#endif
11583 vos_ssr_unprotect(__func__);
11584
11585 return ret;
11586}
11587
Jeff Johnson295189b2012-06-20 16:38:30 -070011588/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011589 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011590 * This function is used to get the key information
11591 */
11592#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011593static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011594 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011595 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011596 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011597 const u8 *mac_addr, void *cookie,
11598 void (*callback)(void *cookie, struct key_params*)
11599 )
11600#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011601static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011602 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011603 struct net_device *ndev,
11604 u8 key_index, const u8 *mac_addr, void *cookie,
11605 void (*callback)(void *cookie, struct key_params*)
11606 )
11607#endif
11608{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011609 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011610 hdd_wext_state_t *pWextState = NULL;
11611 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011612 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011613 hdd_context_t *pHddCtx;
11614 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011615
11616 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011617
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011618 if (NULL == pAdapter)
11619 {
11620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11621 "%s: HDD adapter is Null", __func__);
11622 return -ENODEV;
11623 }
11624
11625 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11626 ret = wlan_hdd_validate_context(pHddCtx);
11627 if (0 != ret)
11628 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011629 return ret;
11630 }
11631
11632 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11633 pRoamProfile = &(pWextState->roamProfile);
11634
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011635 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11636 __func__, hdd_device_modetoString(pAdapter->device_mode),
11637 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011638
Jeff Johnson295189b2012-06-20 16:38:30 -070011639 memset(&params, 0, sizeof(params));
11640
11641 if (CSR_MAX_NUM_KEY <= key_index)
11642 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011643 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011644 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011645 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011646
11647 switch(pRoamProfile->EncryptionType.encryptionType[0])
11648 {
11649 case eCSR_ENCRYPT_TYPE_NONE:
11650 params.cipher = IW_AUTH_CIPHER_NONE;
11651 break;
11652
11653 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11654 case eCSR_ENCRYPT_TYPE_WEP40:
11655 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11656 break;
11657
11658 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11659 case eCSR_ENCRYPT_TYPE_WEP104:
11660 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11661 break;
11662
11663 case eCSR_ENCRYPT_TYPE_TKIP:
11664 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11665 break;
11666
11667 case eCSR_ENCRYPT_TYPE_AES:
11668 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11669 break;
11670
11671 default:
11672 params.cipher = IW_AUTH_CIPHER_NONE;
11673 break;
11674 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011675
c_hpothuaaf19692014-05-17 17:01:48 +053011676 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11677 TRACE_CODE_HDD_CFG80211_GET_KEY,
11678 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011679
Jeff Johnson295189b2012-06-20 16:38:30 -070011680 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11681 params.seq_len = 0;
11682 params.seq = NULL;
11683 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11684 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011685 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011686 return 0;
11687}
11688
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011689#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11690static int wlan_hdd_cfg80211_get_key(
11691 struct wiphy *wiphy,
11692 struct net_device *ndev,
11693 u8 key_index, bool pairwise,
11694 const u8 *mac_addr, void *cookie,
11695 void (*callback)(void *cookie, struct key_params*)
11696 )
11697#else
11698static int wlan_hdd_cfg80211_get_key(
11699 struct wiphy *wiphy,
11700 struct net_device *ndev,
11701 u8 key_index, const u8 *mac_addr, void *cookie,
11702 void (*callback)(void *cookie, struct key_params*)
11703 )
11704#endif
11705{
11706 int ret;
11707
11708 vos_ssr_protect(__func__);
11709#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11710 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
11711 mac_addr, cookie, callback);
11712#else
11713 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
11714 callback);
11715#endif
11716 vos_ssr_unprotect(__func__);
11717
11718 return ret;
11719}
11720
Jeff Johnson295189b2012-06-20 16:38:30 -070011721/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011722 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011723 * This function is used to delete the key information
11724 */
11725#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011726static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011727 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011728 u8 key_index,
11729 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011730 const u8 *mac_addr
11731 )
11732#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011733static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011734 struct net_device *ndev,
11735 u8 key_index,
11736 const u8 *mac_addr
11737 )
11738#endif
11739{
11740 int status = 0;
11741
11742 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011743 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070011744 //it is observed that this is invalidating peer
11745 //key index whenever re-key is done. This is affecting data link.
11746 //It should be ok to ignore del_key.
11747#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011748 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
11749 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011750 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11751 tCsrRoamSetKey setKey;
11752 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011753
Jeff Johnson295189b2012-06-20 16:38:30 -070011754 ENTER();
11755
11756 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
11757 __func__,pAdapter->device_mode);
11758
11759 if (CSR_MAX_NUM_KEY <= key_index)
11760 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011761 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011762 key_index);
11763
11764 return -EINVAL;
11765 }
11766
11767 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11768 setKey.keyId = key_index;
11769
11770 if (mac_addr)
11771 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11772 else
11773 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
11774
11775 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
11776
11777 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011778 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011779 )
11780 {
11781
11782 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070011783 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11784 if( pHostapdState->bssState == BSS_START)
11785 {
11786 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011787
Jeff Johnson295189b2012-06-20 16:38:30 -070011788 if ( status != eHAL_STATUS_SUCCESS )
11789 {
11790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11791 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11792 __LINE__, status );
11793 }
11794 }
11795 }
11796 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011797 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070011798 )
11799 {
11800 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11801
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011802 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11803
11804 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011805 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011806 __func__, setKey.peerMac[0], setKey.peerMac[1],
11807 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070011808 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011809 if(pAdapter->sessionCtx.station.conn_info.connState ==
11810 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070011811 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011812 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011813 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011814
Jeff Johnson295189b2012-06-20 16:38:30 -070011815 if ( 0 != status )
11816 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011817 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011818 "%s: sme_RoamSetKey failure, returned %d",
11819 __func__, status);
11820 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11821 return -EINVAL;
11822 }
11823 }
11824 }
11825#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011826 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011827 return status;
11828}
11829
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011830#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11831static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11832 struct net_device *ndev,
11833 u8 key_index,
11834 bool pairwise,
11835 const u8 *mac_addr
11836 )
11837#else
11838static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11839 struct net_device *ndev,
11840 u8 key_index,
11841 const u8 *mac_addr
11842 )
11843#endif
11844{
11845 int ret;
11846
11847 vos_ssr_protect(__func__);
11848#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11849 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
11850 mac_addr);
11851#else
11852 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
11853#endif
11854 vos_ssr_unprotect(__func__);
11855
11856 return ret;
11857}
11858
Jeff Johnson295189b2012-06-20 16:38:30 -070011859/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011860 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011861 * This function is used to set the default tx key index
11862 */
11863#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011864static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011865 struct net_device *ndev,
11866 u8 key_index,
11867 bool unicast, bool multicast)
11868#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011869static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011870 struct net_device *ndev,
11871 u8 key_index)
11872#endif
11873{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011874 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011875 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011876 hdd_wext_state_t *pWextState;
11877 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011878 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011879
11880 ENTER();
11881
Gopichand Nakkala29149562013-05-10 21:43:41 +053011882 if ((NULL == pAdapter))
11883 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011885 "invalid adapter");
11886 return -EINVAL;
11887 }
11888
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011889 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11890 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
11891 pAdapter->sessionId, key_index));
11892
Gopichand Nakkala29149562013-05-10 21:43:41 +053011893 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11894 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11895
11896 if ((NULL == pWextState) || (NULL == pHddStaCtx))
11897 {
11898 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11899 "invalid Wext state or HDD context");
11900 return -EINVAL;
11901 }
11902
Arif Hussain6d2a3322013-11-17 19:50:10 -080011903 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011904 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011905
Jeff Johnson295189b2012-06-20 16:38:30 -070011906 if (CSR_MAX_NUM_KEY <= key_index)
11907 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011908 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011909 key_index);
11910
11911 return -EINVAL;
11912 }
11913
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011914 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11915 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011916 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011917 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011918 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011919 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011920
Jeff Johnson295189b2012-06-20 16:38:30 -070011921 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011922 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011923 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011924 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011925 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080011926 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011927 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080011928 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070011929 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011930 {
11931 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070011932 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011933
Jeff Johnson295189b2012-06-20 16:38:30 -070011934 tCsrRoamSetKey setKey;
11935 v_U32_t roamId= 0xFF;
11936 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011937
11938 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011939 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011940
Jeff Johnson295189b2012-06-20 16:38:30 -070011941 Keys->defaultIndex = (u8)key_index;
11942 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11943 setKey.keyId = key_index;
11944 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011945
11946 vos_mem_copy(&setKey.Key[0],
11947 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011948 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011949
Gopichand Nakkala29149562013-05-10 21:43:41 +053011950 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011951
11952 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070011953 &pHddStaCtx->conn_info.bssId[0],
11954 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011955
Gopichand Nakkala29149562013-05-10 21:43:41 +053011956 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
11957 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
11958 eCSR_ENCRYPT_TYPE_WEP104)
11959 {
11960 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
11961 even though ap is configured for WEP-40 encryption. In this canse the key length
11962 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
11963 type(104) and switching encryption type to 40*/
11964 pWextState->roamProfile.EncryptionType.encryptionType[0] =
11965 eCSR_ENCRYPT_TYPE_WEP40;
11966 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
11967 eCSR_ENCRYPT_TYPE_WEP40;
11968 }
11969
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011970 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011971 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011972
Jeff Johnson295189b2012-06-20 16:38:30 -070011973 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011974 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011975 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011976
Jeff Johnson295189b2012-06-20 16:38:30 -070011977 if ( 0 != status )
11978 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011979 hddLog(VOS_TRACE_LEVEL_ERROR,
11980 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011981 status);
11982 return -EINVAL;
11983 }
11984 }
11985 }
11986
11987 /* In SoftAp mode setting key direction for default mode */
11988 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
11989 {
11990 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
11991 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
11992 (eCSR_ENCRYPT_TYPE_AES !=
11993 pWextState->roamProfile.EncryptionType.encryptionType[0])
11994 )
11995 {
11996 /* Saving key direction for default key index to TX default */
11997 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11998 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
11999 }
12000 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012001 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012002 return status;
12003}
12004
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012005#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12006static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12007 struct net_device *ndev,
12008 u8 key_index,
12009 bool unicast, bool multicast)
12010#else
12011static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12012 struct net_device *ndev,
12013 u8 key_index)
12014#endif
12015{
12016 int ret;
12017 vos_ssr_protect(__func__);
12018#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12019 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
12020 multicast);
12021#else
12022 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
12023#endif
12024 vos_ssr_unprotect(__func__);
12025
12026 return ret;
12027}
12028
Jeff Johnson295189b2012-06-20 16:38:30 -070012029/*
12030 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12031 * This function is used to inform the BSS details to nl80211 interface.
12032 */
12033static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12034 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12035{
12036 struct net_device *dev = pAdapter->dev;
12037 struct wireless_dev *wdev = dev->ieee80211_ptr;
12038 struct wiphy *wiphy = wdev->wiphy;
12039 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12040 int chan_no;
12041 int ie_length;
12042 const char *ie;
12043 unsigned int freq;
12044 struct ieee80211_channel *chan;
12045 int rssi = 0;
12046 struct cfg80211_bss *bss = NULL;
12047
Jeff Johnson295189b2012-06-20 16:38:30 -070012048 if( NULL == pBssDesc )
12049 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012050 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012051 return bss;
12052 }
12053
12054 chan_no = pBssDesc->channelId;
12055 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12056 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12057
12058 if( NULL == ie )
12059 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012060 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012061 return bss;
12062 }
12063
12064#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12065 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12066 {
12067 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12068 }
12069 else
12070 {
12071 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12072 }
12073#else
12074 freq = ieee80211_channel_to_frequency(chan_no);
12075#endif
12076
12077 chan = __ieee80211_get_channel(wiphy, freq);
12078
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012079 if (!chan) {
12080 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12081 return NULL;
12082 }
12083
Abhishek Singhaee43942014-06-16 18:55:47 +053012084 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012085
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012086 return cfg80211_inform_bss(wiphy, chan,
12087#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12088 CFG80211_BSS_FTYPE_UNKNOWN,
12089#endif
12090 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012091 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012092 pBssDesc->capabilityInfo,
12093 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012094 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012095}
12096
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012097/*
12098 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12099 * interface that BSS might have been lost.
12100 * @pAdapter: adaptor
12101 * @bssid: bssid which might have been lost
12102 *
12103 * Return: bss which is unlinked from kernel cache
12104 */
12105struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12106 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12107{
12108 struct net_device *dev = pAdapter->dev;
12109 struct wireless_dev *wdev = dev->ieee80211_ptr;
12110 struct wiphy *wiphy = wdev->wiphy;
12111 struct cfg80211_bss *bss = NULL;
12112
12113 bss = cfg80211_get_bss(wiphy, NULL, bssid,
12114 NULL,
12115 0,
12116#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && !defined(WITH_BACKPORTS) \
12117 && !defined(IEEE80211_PRIVACY)
12118 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
12119#else
12120 IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
12121#endif
12122 if (bss == NULL) {
12123 hddLog(LOGE, FL("BSS not present"));
12124 } else {
12125 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12126 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12127 cfg80211_unlink_bss(wiphy, bss);
12128 }
12129 return bss;
12130}
Jeff Johnson295189b2012-06-20 16:38:30 -070012131
12132
12133/*
12134 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12135 * This function is used to inform the BSS details to nl80211 interface.
12136 */
12137struct cfg80211_bss*
12138wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12139 tSirBssDescription *bss_desc
12140 )
12141{
12142 /*
12143 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12144 already exists in bss data base of cfg80211 for that particular BSS ID.
12145 Using cfg80211_inform_bss_frame to update the bss entry instead of
12146 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12147 now there is no possibility to get the mgmt(probe response) frame from PE,
12148 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12149 cfg80211_inform_bss_frame.
12150 */
12151 struct net_device *dev = pAdapter->dev;
12152 struct wireless_dev *wdev = dev->ieee80211_ptr;
12153 struct wiphy *wiphy = wdev->wiphy;
12154 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012155#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12156 qcom_ie_age *qie_age = NULL;
12157 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12158#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012159 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012160#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012161 const char *ie =
12162 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12163 unsigned int freq;
12164 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012165 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012166 struct cfg80211_bss *bss_status = NULL;
12167 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12168 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012169 hdd_context_t *pHddCtx;
12170 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012171#ifdef WLAN_OPEN_SOURCE
12172 struct timespec ts;
12173#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012174
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012175
Wilson Yangf80a0542013-10-07 13:02:37 -070012176 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12177 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012178 if (0 != status)
12179 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012180 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012181 }
12182
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012183 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012184 if (!mgmt)
12185 {
12186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12187 "%s: memory allocation failed ", __func__);
12188 return NULL;
12189 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012190
Jeff Johnson295189b2012-06-20 16:38:30 -070012191 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012192
12193#ifdef WLAN_OPEN_SOURCE
12194 /* Android does not want the timestamp from the frame.
12195 Instead it wants a monotonic increasing value */
12196 get_monotonic_boottime(&ts);
12197 mgmt->u.probe_resp.timestamp =
12198 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12199#else
12200 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012201 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12202 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012203
12204#endif
12205
Jeff Johnson295189b2012-06-20 16:38:30 -070012206 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12207 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012208
12209#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12210 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12211 /* Assuming this is the last IE, copy at the end */
12212 ie_length -=sizeof(qcom_ie_age);
12213 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12214 qie_age->element_id = QCOM_VENDOR_IE_ID;
12215 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12216 qie_age->oui_1 = QCOM_OUI1;
12217 qie_age->oui_2 = QCOM_OUI2;
12218 qie_age->oui_3 = QCOM_OUI3;
12219 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Deepthi Gowri4480a3f2016-05-18 19:30:17 +053012220 qie_age->age = vos_timer_get_system_time() - bss_desc->nReceivedTime;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012221#endif
12222
Jeff Johnson295189b2012-06-20 16:38:30 -070012223 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012224 if (bss_desc->fProbeRsp)
12225 {
12226 mgmt->frame_control |=
12227 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12228 }
12229 else
12230 {
12231 mgmt->frame_control |=
12232 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12233 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012234
12235#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012236 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012237 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12238 {
12239 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12240 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012241 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012242 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12243
12244 {
12245 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12246 }
12247 else
12248 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012249 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12250 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012251 kfree(mgmt);
12252 return NULL;
12253 }
12254#else
12255 freq = ieee80211_channel_to_frequency(chan_no);
12256#endif
12257 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012258 /*when the band is changed on the fly using the GUI, three things are done
12259 * 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)
12260 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12261 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12262 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12263 * and discards the channels correponding to previous band and calls back with zero bss results.
12264 * 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
12265 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12266 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12267 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12268 * So drop the bss and continue to next bss.
12269 */
12270 if(chan == NULL)
12271 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053012272 hddLog(VOS_TRACE_LEVEL_ERROR,
12273 FL("chan pointer is NULL, chan_no: %d freq: %d"),
12274 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070012275 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012276 return NULL;
12277 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012278 /*To keep the rssi icon of the connected AP in the scan window
12279 *and the rssi icon of the wireless networks in sync
12280 * */
12281 if (( eConnectionState_Associated ==
12282 pAdapter->sessionCtx.station.conn_info.connState ) &&
12283 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12284 pAdapter->sessionCtx.station.conn_info.bssId,
12285 WNI_CFG_BSSID_LEN)) &&
12286 (pHddCtx->hdd_wlan_suspended == FALSE))
12287 {
12288 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12289 rssi = (pAdapter->rssi * 100);
12290 }
12291 else
12292 {
12293 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12294 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012295
Nirav Shah20ac06f2013-12-12 18:14:06 +053012296 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012297 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12298 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012299
Jeff Johnson295189b2012-06-20 16:38:30 -070012300 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12301 frame_len, rssi, GFP_KERNEL);
12302 kfree(mgmt);
12303 return bss_status;
12304}
12305
12306/*
12307 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12308 * This function is used to update the BSS data base of CFG8011
12309 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012310struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012311 tCsrRoamInfo *pRoamInfo
12312 )
12313{
12314 tCsrRoamConnectedProfile roamProfile;
12315 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12316 struct cfg80211_bss *bss = NULL;
12317
12318 ENTER();
12319
12320 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12321 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12322
12323 if (NULL != roamProfile.pBssDesc)
12324 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012325 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12326 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012327
12328 if (NULL == bss)
12329 {
12330 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12331 __func__);
12332 }
12333
12334 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12335 }
12336 else
12337 {
12338 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12339 __func__);
12340 }
12341 return bss;
12342}
12343
12344/*
12345 * FUNCTION: wlan_hdd_cfg80211_update_bss
12346 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012347static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12348 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012349 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012350{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012351 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012352 tCsrScanResultInfo *pScanResult;
12353 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012354 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012355 tScanResultHandle pResult;
12356 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012357 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012358 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012359 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012360
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012361 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12362 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12363 NO_SESSION, pAdapter->sessionId));
12364
Wilson Yangf80a0542013-10-07 13:02:37 -070012365 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012366 ret = wlan_hdd_validate_context(pHddCtx);
12367 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070012368 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012369 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070012370 }
12371
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012372 if (pAdapter->request != NULL)
12373 {
12374 if ((pAdapter->request->n_ssids == 1)
12375 && (pAdapter->request->ssids != NULL)
12376 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12377 is_p2p_scan = true;
12378 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012379 /*
12380 * start getting scan results and populate cgf80211 BSS database
12381 */
12382 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12383
12384 /* no scan results */
12385 if (NULL == pResult)
12386 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012387 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12388 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012389 wlan_hdd_get_frame_logs(pAdapter,
12390 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012391 return status;
12392 }
12393
12394 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12395
12396 while (pScanResult)
12397 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012398 /*
12399 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12400 * entry already exists in bss data base of cfg80211 for that
12401 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12402 * bss entry instead of cfg80211_inform_bss, But this call expects
12403 * mgmt packet as input. As of now there is no possibility to get
12404 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012405 * ieee80211_mgmt(probe response) and passing to c
12406 * fg80211_inform_bss_frame.
12407 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012408 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12409 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12410 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012411 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12412 continue; //Skip the non p2p bss entries
12413 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012414 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12415 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012416
Jeff Johnson295189b2012-06-20 16:38:30 -070012417
12418 if (NULL == bss_status)
12419 {
12420 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012421 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012422 }
12423 else
12424 {
Yue Maf49ba872013-08-19 12:04:25 -070012425 cfg80211_put_bss(
12426#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12427 wiphy,
12428#endif
12429 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012430 }
12431
12432 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12433 }
12434
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012435 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012436 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012437 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012438}
12439
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012440void
12441hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12442{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012443 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012444 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012445} /****** end hddPrintMacAddr() ******/
12446
12447void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012448hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012449{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012450 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012451 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012452 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12453 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12454 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012455} /****** end hddPrintPmkId() ******/
12456
12457//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12458//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12459
12460//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12461//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12462
12463#define dump_bssid(bssid) \
12464 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012465 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12466 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012467 }
12468
12469#define dump_pmkid(pMac, pmkid) \
12470 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012471 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12472 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012473 }
12474
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012475#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012476/*
12477 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12478 * This function is used to notify the supplicant of a new PMKSA candidate.
12479 */
12480int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012481 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012482 int index, bool preauth )
12483{
Jeff Johnsone7245742012-09-05 17:12:55 -070012484#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012485 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012486 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012487
12488 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012489 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012490
12491 if( NULL == pRoamInfo )
12492 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012493 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012494 return -EINVAL;
12495 }
12496
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012497 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12498 {
12499 dump_bssid(pRoamInfo->bssid);
12500 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012501 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012502 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012503#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012504 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012505}
12506#endif //FEATURE_WLAN_LFR
12507
Yue Maef608272013-04-08 23:09:17 -070012508#ifdef FEATURE_WLAN_LFR_METRICS
12509/*
12510 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12511 * 802.11r/LFR metrics reporting function to report preauth initiation
12512 *
12513 */
12514#define MAX_LFR_METRICS_EVENT_LENGTH 100
12515VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12516 tCsrRoamInfo *pRoamInfo)
12517{
12518 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12519 union iwreq_data wrqu;
12520
12521 ENTER();
12522
12523 if (NULL == pAdapter)
12524 {
12525 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12526 return VOS_STATUS_E_FAILURE;
12527 }
12528
12529 /* create the event */
12530 memset(&wrqu, 0, sizeof(wrqu));
12531 memset(metrics_notification, 0, sizeof(metrics_notification));
12532
12533 wrqu.data.pointer = metrics_notification;
12534 wrqu.data.length = scnprintf(metrics_notification,
12535 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12536 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12537
12538 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12539
12540 EXIT();
12541
12542 return VOS_STATUS_SUCCESS;
12543}
12544
12545/*
12546 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12547 * 802.11r/LFR metrics reporting function to report preauth completion
12548 * or failure
12549 */
12550VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12551 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12552{
12553 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12554 union iwreq_data wrqu;
12555
12556 ENTER();
12557
12558 if (NULL == pAdapter)
12559 {
12560 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12561 return VOS_STATUS_E_FAILURE;
12562 }
12563
12564 /* create the event */
12565 memset(&wrqu, 0, sizeof(wrqu));
12566 memset(metrics_notification, 0, sizeof(metrics_notification));
12567
12568 scnprintf(metrics_notification, sizeof(metrics_notification),
12569 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12570 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12571
12572 if (1 == preauth_status)
12573 strncat(metrics_notification, " TRUE", 5);
12574 else
12575 strncat(metrics_notification, " FALSE", 6);
12576
12577 wrqu.data.pointer = metrics_notification;
12578 wrqu.data.length = strlen(metrics_notification);
12579
12580 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12581
12582 EXIT();
12583
12584 return VOS_STATUS_SUCCESS;
12585}
12586
12587/*
12588 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12589 * 802.11r/LFR metrics reporting function to report handover initiation
12590 *
12591 */
12592VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12593 tCsrRoamInfo *pRoamInfo)
12594{
12595 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12596 union iwreq_data wrqu;
12597
12598 ENTER();
12599
12600 if (NULL == pAdapter)
12601 {
12602 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12603 return VOS_STATUS_E_FAILURE;
12604 }
12605
12606 /* create the event */
12607 memset(&wrqu, 0, sizeof(wrqu));
12608 memset(metrics_notification, 0, sizeof(metrics_notification));
12609
12610 wrqu.data.pointer = metrics_notification;
12611 wrqu.data.length = scnprintf(metrics_notification,
12612 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12613 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12614
12615 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12616
12617 EXIT();
12618
12619 return VOS_STATUS_SUCCESS;
12620}
12621#endif
12622
Jeff Johnson295189b2012-06-20 16:38:30 -070012623/*
12624 * FUNCTION: hdd_cfg80211_scan_done_callback
12625 * scanning callback function, called after finishing scan
12626 *
12627 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012628static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012629 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12630{
12631 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012632 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012633 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012634 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012635 struct cfg80211_scan_request *req = NULL;
12636 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012637 bool aborted = false;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012638#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12639 bool iface_down = false;
12640#endif
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012641 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012642 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012643 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012644
12645 ENTER();
12646
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012647 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012648 if (NULL == pHddCtx) {
12649 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012650 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012651 }
12652
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012653#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12654 if (!(pAdapter->dev->flags & IFF_UP))
12655 {
12656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012657 iface_down = true;
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012658 }
12659#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012660 pScanInfo = &pHddCtx->scan_info;
12661
Jeff Johnson295189b2012-06-20 16:38:30 -070012662 hddLog(VOS_TRACE_LEVEL_INFO,
12663 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012664 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012665 __func__, halHandle, pContext, (int) scanId, (int) status);
12666
Kiet Lamac06e2c2013-10-23 16:25:07 +053012667 pScanInfo->mScanPendingCounter = 0;
12668
Jeff Johnson295189b2012-06-20 16:38:30 -070012669 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012670 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012671 &pScanInfo->scan_req_completion_event,
12672 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012673 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012674 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012675 hddLog(VOS_TRACE_LEVEL_ERROR,
12676 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012677 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012678 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012679 }
12680
Yue Maef608272013-04-08 23:09:17 -070012681 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012682 {
12683 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012684 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012685 }
12686
12687 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012688 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012689 {
12690 hddLog(VOS_TRACE_LEVEL_INFO,
12691 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012692 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012693 (int) scanId);
12694 }
12695
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012696#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012697 if (!iface_down)
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012698#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012699 {
12700 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
12701 pAdapter);
12702 if (0 > ret)
12703 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012704 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012705
Jeff Johnson295189b2012-06-20 16:38:30 -070012706 /* If any client wait scan result through WEXT
12707 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012708 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012709 {
12710 /* The other scan request waiting for current scan finish
12711 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012712 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012713 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012714 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012715 }
12716 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012717 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012718 {
12719 struct net_device *dev = pAdapter->dev;
12720 union iwreq_data wrqu;
12721 int we_event;
12722 char *msg;
12723
12724 memset(&wrqu, '\0', sizeof(wrqu));
12725 we_event = SIOCGIWSCAN;
12726 msg = NULL;
12727 wireless_send_event(dev, we_event, &wrqu, msg);
12728 }
12729 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012730 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012731
12732 /* Get the Scan Req */
12733 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053012734 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012735
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012736 /* Scan is no longer pending */
12737 pScanInfo->mScanPending = VOS_FALSE;
12738
mukul sharmae7041822015-12-03 15:09:21 +053012739 if (!req || req->wiphy == NULL)
Jeff Johnson295189b2012-06-20 16:38:30 -070012740 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012741 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
mukul sharmae7041822015-12-03 15:09:21 +053012742 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070012743 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012744 }
12745
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012746 /* last_scan_timestamp is used to decide if new scan
12747 * is needed or not on station interface. If last station
12748 * scan time and new station scan time is less then
12749 * last_scan_timestamp ; driver will return cached scan.
12750 */
12751 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12752 {
12753 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12754
12755 if ( req->n_channels )
12756 {
12757 for (i = 0; i < req->n_channels ; i++ )
12758 {
12759 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12760 }
12761 /* store no of channel scanned */
12762 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
12763 }
12764
12765 }
12766
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070012767 /*
12768 * cfg80211_scan_done informing NL80211 about completion
12769 * of scanning
12770 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012771 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
12772 {
12773 aborted = true;
12774 }
mukul sharmae7041822015-12-03 15:09:21 +053012775
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012776#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12777 if (!iface_down)
12778#endif
12779 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053012780
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012781 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070012782
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012783allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053012784 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
12785 ) && (pHddCtx->spoofMacAddr.isEnabled
12786 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053012787 /* Generate new random mac addr for next scan */
12788 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053012789
12790 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
12791 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053012792 }
12793
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012794 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012795 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012796
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012797 /* Acquire wakelock to handle the case where APP's tries to suspend
12798 * immediatly after the driver gets connect request(i.e after scan)
12799 * from supplicant, this result in app's is suspending and not able
12800 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012801 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012802
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012803#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12804 if (!iface_down)
12805#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012806#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012807 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012808#endif
12809
Jeff Johnson295189b2012-06-20 16:38:30 -070012810 EXIT();
12811 return 0;
12812}
12813
12814/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053012815 * FUNCTION: hdd_isConnectionInProgress
12816 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012817 *
12818 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012819v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012820{
12821 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12822 hdd_station_ctx_t *pHddStaCtx = NULL;
12823 hdd_adapter_t *pAdapter = NULL;
12824 VOS_STATUS status = 0;
12825 v_U8_t staId = 0;
12826 v_U8_t *staMac = NULL;
12827
c_hpothu9b781ba2013-12-30 20:57:45 +053012828 if (TRUE == pHddCtx->btCoexModeSet)
12829 {
12830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053012831 FL("BTCoex Mode operation in progress"));
12832 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053012833 }
12834
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012835 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12836
12837 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12838 {
12839 pAdapter = pAdapterNode->pAdapter;
12840
12841 if( pAdapter )
12842 {
12843 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012844 "%s: Adapter with device mode %s (%d) exists",
12845 __func__, hdd_device_modetoString(pAdapter->device_mode),
12846 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012847 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053012848 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12849 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
12850 (eConnectionState_Connecting ==
12851 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12852 {
12853 hddLog(VOS_TRACE_LEVEL_ERROR,
12854 "%s: %p(%d) Connection is in progress", __func__,
12855 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12856 return VOS_TRUE;
12857 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012858 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053012859 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012860 {
12861 hddLog(VOS_TRACE_LEVEL_ERROR,
12862 "%s: %p(%d) Reassociation is in progress", __func__,
12863 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12864 return VOS_TRUE;
12865 }
12866 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012867 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12868 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012869 {
12870 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12871 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012872 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012873 {
12874 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
12875 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012876 "%s: client " MAC_ADDRESS_STR
12877 " is in the 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 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
12883 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
12884 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012885 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12886 ptSapContext pSapCtx = NULL;
12887 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12888 if(pSapCtx == NULL){
12889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12890 FL("psapCtx is NULL"));
12891 return VOS_FALSE;
12892 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012893 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
12894 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012895 if ((pSapCtx->aStaInfo[staId].isUsed) &&
12896 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012897 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012898 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012899
12900 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012901 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
12902 "middle of WPS/EAPOL exchange.", __func__,
12903 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012904 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012905 }
12906 }
12907 }
12908 }
12909 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12910 pAdapterNode = pNext;
12911 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053012912 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012913}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012914
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053012915/**
12916 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
12917 * to the Scan request
12918 * @scanRequest: Pointer to the csr scan request
12919 * @request: Pointer to the scan request from supplicant
12920 *
12921 * Return: None
12922 */
12923#ifdef CFG80211_SCAN_BSSID
12924static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
12925 struct cfg80211_scan_request *request)
12926{
12927 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
12928}
12929#else
12930static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
12931 struct cfg80211_scan_request *request)
12932{
12933}
12934#endif
12935
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012936/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012937 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070012938 * this scan respond to scan trigger and update cfg80211 scan database
12939 * later, scan dump command can be used to recieve scan results
12940 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012941int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080012942#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12943 struct net_device *dev,
12944#endif
12945 struct cfg80211_scan_request *request)
12946{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012947 hdd_adapter_t *pAdapter = NULL;
12948 hdd_context_t *pHddCtx = NULL;
12949 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012950 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012951 tCsrScanRequest scanRequest;
12952 tANI_U8 *channelList = NULL, i;
12953 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012954 int status;
12955 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012956 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012957 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053012958 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053012959 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012960
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012961#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
12962 struct net_device *dev = NULL;
12963 if (NULL == request)
12964 {
12965 hddLog(VOS_TRACE_LEVEL_ERROR,
12966 "%s: scan req param null", __func__);
12967 return -EINVAL;
12968 }
12969 dev = request->wdev->netdev;
12970#endif
12971
12972 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12973 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
12974 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12975
Jeff Johnson295189b2012-06-20 16:38:30 -070012976 ENTER();
12977
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012978 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12979 __func__, hdd_device_modetoString(pAdapter->device_mode),
12980 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012981
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012982 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012983 if (0 != status)
12984 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012985 return status;
12986 }
12987
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012988 if (NULL == pwextBuf)
12989 {
12990 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
12991 __func__);
12992 return -EIO;
12993 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012994 cfg_param = pHddCtx->cfg_ini;
12995 pScanInfo = &pHddCtx->scan_info;
12996
Jeff Johnson295189b2012-06-20 16:38:30 -070012997#ifdef WLAN_BTAMP_FEATURE
12998 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012999 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013000 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013001 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013002 "%s: No scanning when AMP is on", __func__);
13003 return -EOPNOTSUPP;
13004 }
13005#endif
13006 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013007 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013008 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013009 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013010 "%s: Not scanning on device_mode = %s (%d)",
13011 __func__, hdd_device_modetoString(pAdapter->device_mode),
13012 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013013 return -EOPNOTSUPP;
13014 }
13015
13016 if (TRUE == pScanInfo->mScanPending)
13017 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013018 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13019 {
13020 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13021 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013022 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013023 }
13024
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013025 // Don't allow scan if PNO scan is going on.
13026 if (pHddCtx->isPnoEnable)
13027 {
13028 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13029 FL("pno scan in progress"));
13030 return -EBUSY;
13031 }
13032
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013033 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013034 //Channel and action frame is pending
13035 //Otherwise Cancel Remain On Channel and allow Scan
13036 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013037 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013038 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013039 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013040 return -EBUSY;
13041 }
13042
Jeff Johnson295189b2012-06-20 16:38:30 -070013043 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13044 {
13045 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013046 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013047 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013048 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013049 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13050 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013051 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013052 "%s: MAX TM Level Scan not allowed", __func__);
13053 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013054 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013055 }
13056 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13057
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013058 /* Check if scan is allowed at this point of time.
13059 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013060 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013061 {
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013062 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
13063 if (SCAN_ABORT_THRESHOLD < pHddCtx->con_scan_abort_cnt) {
13064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13065 FL("Triggering SSR, SSR status = %d"), status);
13066 vos_wlanRestart();
13067 }
13068 else
13069 pHddCtx->con_scan_abort_cnt++;
13070
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013071 return -EBUSY;
13072 }
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013073 pHddCtx->con_scan_abort_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013074
Jeff Johnson295189b2012-06-20 16:38:30 -070013075 vos_mem_zero( &scanRequest, sizeof(scanRequest));
13076
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013077 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
13078 * Becasue of this, driver is assuming that this is not wildcard scan and so
13079 * is not aging out the scan results.
13080 */
13081 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070013082 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013083 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013084 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013085
13086 if ((request->ssids) && (0 < request->n_ssids))
13087 {
13088 tCsrSSIDInfo *SsidInfo;
13089 int j;
13090 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
13091 /* Allocate num_ssid tCsrSSIDInfo structure */
13092 SsidInfo = scanRequest.SSIDs.SSIDList =
13093 ( tCsrSSIDInfo *)vos_mem_malloc(
13094 request->n_ssids*sizeof(tCsrSSIDInfo));
13095
13096 if(NULL == scanRequest.SSIDs.SSIDList)
13097 {
13098 hddLog(VOS_TRACE_LEVEL_ERROR,
13099 "%s: memory alloc failed SSIDInfo buffer", __func__);
13100 return -ENOMEM;
13101 }
13102
13103 /* copy all the ssid's and their length */
13104 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
13105 {
13106 /* get the ssid length */
13107 SsidInfo->SSID.length = request->ssids[j].ssid_len;
13108 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
13109 SsidInfo->SSID.length);
13110 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
13111 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
13112 j, SsidInfo->SSID.ssId);
13113 }
13114 /* set the scan type to active */
13115 scanRequest.scanType = eSIR_ACTIVE_SCAN;
13116 }
13117 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013118 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013119 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13120 TRACE_CODE_HDD_CFG80211_SCAN,
13121 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070013122 /* set the scan type to active */
13123 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070013124 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013125 else
13126 {
13127 /*Set the scan type to default type, in this case it is ACTIVE*/
13128 scanRequest.scanType = pScanInfo->scan_mode;
13129 }
13130 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
13131 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070013132
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013133 csr_scan_request_assign_bssid(&scanRequest, request);
13134
Jeff Johnson295189b2012-06-20 16:38:30 -070013135 /* set BSSType to default type */
13136 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
13137
13138 /*TODO: scan the requested channels only*/
13139
13140 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013141 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070013142 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013143 hddLog(VOS_TRACE_LEVEL_WARN,
13144 "No of Scan Channels exceeded limit: %d", request->n_channels);
13145 request->n_channels = MAX_CHANNEL;
13146 }
13147
13148 hddLog(VOS_TRACE_LEVEL_INFO,
13149 "No of Scan Channels: %d", request->n_channels);
13150
13151
13152 if( request->n_channels )
13153 {
13154 char chList [(request->n_channels*5)+1];
13155 int len;
13156 channelList = vos_mem_malloc( request->n_channels );
13157 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053013158 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013159 hddLog(VOS_TRACE_LEVEL_ERROR,
13160 "%s: memory alloc failed channelList", __func__);
13161 status = -ENOMEM;
13162 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053013163 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013164
13165 for( i = 0, len = 0; i < request->n_channels ; i++ )
13166 {
13167 channelList[i] = request->channels[i]->hw_value;
13168 len += snprintf(chList+len, 5, "%d ", channelList[i]);
13169 }
13170
Nirav Shah20ac06f2013-12-12 18:14:06 +053013171 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013172 "Channel-List: %s ", chList);
13173 }
c_hpothu53512302014-04-15 18:49:53 +053013174
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013175 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13176 scanRequest.ChannelInfo.ChannelList = channelList;
13177
13178 /* set requestType to full scan */
13179 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13180
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013181 /* if there is back to back scan happening in driver with in
13182 * nDeferScanTimeInterval interval driver should defer new scan request
13183 * and should provide last cached scan results instead of new channel list.
13184 * This rule is not applicable if scan is p2p scan.
13185 * This condition will work only in case when last request no of channels
13186 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013187 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013188 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013189 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013190
Sushant Kaushik86592172015-04-27 16:35:03 +053013191 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13192 /* if wps ie is NULL , then only defer scan */
13193 if ( pWpsIe == NULL &&
13194 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013195 {
13196 if ( pScanInfo->last_scan_timestamp !=0 &&
13197 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13198 {
13199 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13200 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13201 vos_mem_compare(pScanInfo->last_scan_channelList,
13202 channelList, pScanInfo->last_scan_numChannels))
13203 {
13204 hddLog(VOS_TRACE_LEVEL_WARN,
13205 " New and old station scan time differ is less then %u",
13206 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13207
13208 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013209 pAdapter);
13210
Agarwal Ashish57e84372014-12-05 18:26:53 +053013211 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013212 "Return old cached scan as all channels and no of channels are same");
13213
Agarwal Ashish57e84372014-12-05 18:26:53 +053013214 if (0 > ret)
13215 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013216
Agarwal Ashish57e84372014-12-05 18:26:53 +053013217 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013218
13219 status = eHAL_STATUS_SUCCESS;
13220 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013221 }
13222 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013223 }
13224
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013225 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13226 * search (Flush on both full scan and social scan but not on single
13227 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13228 */
13229
13230 /* Supplicant does single channel scan after 8-way handshake
13231 * and in that case driver shoudnt flush scan results. If
13232 * driver flushes the scan results here and unfortunately if
13233 * the AP doesnt respond to our probe req then association
13234 * fails which is not desired
13235 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013236 if ((request->n_ssids == 1)
13237 && (request->ssids != NULL)
13238 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13239 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013240
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013241 if( is_p2p_scan ||
13242 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013243 {
13244 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13245 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13246 pAdapter->sessionId );
13247 }
13248
13249 if( request->ie_len )
13250 {
13251 /* save this for future association (join requires this) */
13252 /*TODO: Array needs to be converted to dynamic allocation,
13253 * as multiple ie.s can be sent in cfg80211_scan_request structure
13254 * CR 597966
13255 */
13256 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13257 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13258 pScanInfo->scanAddIE.length = request->ie_len;
13259
13260 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13261 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13262 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013263 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013264 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013265 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013266 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13267 memcpy( pwextBuf->roamProfile.addIEScan,
13268 request->ie, request->ie_len);
13269 }
13270 else
13271 {
13272 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13273 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013274 }
13275
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013276 }
13277 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13278 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13279
13280 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13281 request->ie_len);
13282 if (pP2pIe != NULL)
13283 {
13284#ifdef WLAN_FEATURE_P2P_DEBUG
13285 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13286 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13287 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013288 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013289 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13290 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13291 "Go nego completed to Connection is started");
13292 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13293 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013294 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013295 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13296 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013297 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013298 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13299 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13300 "Disconnected state to Connection is started");
13301 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13302 "for 4way Handshake");
13303 }
13304#endif
13305
13306 /* no_cck will be set during p2p find to disable 11b rates */
13307 if(TRUE == request->no_cck)
13308 {
13309 hddLog(VOS_TRACE_LEVEL_INFO,
13310 "%s: This is a P2P Search", __func__);
13311 scanRequest.p2pSearch = 1;
13312
13313 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013314 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013315 /* set requestType to P2P Discovery */
13316 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13317 }
13318
13319 /*
13320 Skip Dfs Channel in case of P2P Search
13321 if it is set in ini file
13322 */
13323 if(cfg_param->skipDfsChnlInP2pSearch)
13324 {
13325 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013326 }
13327 else
13328 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013329 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013330 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013331
Agarwal Ashish4f616132013-12-30 23:32:50 +053013332 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013333 }
13334 }
13335
13336 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13337
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013338#ifdef FEATURE_WLAN_TDLS
13339 /* if tdls disagree scan right now, return immediately.
13340 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13341 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13342 */
13343 status = wlan_hdd_tdls_scan_callback (pAdapter,
13344 wiphy,
13345#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13346 dev,
13347#endif
13348 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013349 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013350 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053013351 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013352 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13353 "scan rejected %d", __func__, status);
13354 else
13355 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13356 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013357 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053013358 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013359 }
13360#endif
13361
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013362 /* acquire the wakelock to avoid the apps suspend during the scan. To
13363 * address the following issues.
13364 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13365 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13366 * for long time, this result in apps running at full power for long time.
13367 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13368 * be stuck in full power because of resume BMPS
13369 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013370 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013371
Nirav Shah20ac06f2013-12-12 18:14:06 +053013372 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13373 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013374 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13375 scanRequest.requestType, scanRequest.scanType,
13376 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013377 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13378
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013379 if (pHddCtx->spoofMacAddr.isEnabled &&
13380 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013381 {
13382 hddLog(VOS_TRACE_LEVEL_INFO,
13383 "%s: MAC Spoofing enabled for current scan", __func__);
13384 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13385 * to fill TxBds for probe request during current scan
13386 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013387 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013388 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013389
13390 if(status != VOS_STATUS_SUCCESS)
13391 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013392 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013393 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013394#ifdef FEATURE_WLAN_TDLS
13395 wlan_hdd_tdls_scan_done_callback(pAdapter);
13396#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013397 goto free_mem;
13398 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013399 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013400 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013401 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013402 pAdapter->sessionId, &scanRequest, &scanId,
13403 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013404
Jeff Johnson295189b2012-06-20 16:38:30 -070013405 if (eHAL_STATUS_SUCCESS != status)
13406 {
13407 hddLog(VOS_TRACE_LEVEL_ERROR,
13408 "%s: sme_ScanRequest returned error %d", __func__, status);
13409 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013410 if(eHAL_STATUS_RESOURCES == status)
13411 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013412 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13413 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013414 status = -EBUSY;
13415 } else {
13416 status = -EIO;
13417 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013418 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013419
13420#ifdef FEATURE_WLAN_TDLS
13421 wlan_hdd_tdls_scan_done_callback(pAdapter);
13422#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013423 goto free_mem;
13424 }
13425
13426 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013427 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013428 pAdapter->request = request;
13429 pScanInfo->scanId = scanId;
13430
13431 complete(&pScanInfo->scan_req_completion_event);
13432
13433free_mem:
13434 if( scanRequest.SSIDs.SSIDList )
13435 {
13436 vos_mem_free(scanRequest.SSIDs.SSIDList);
13437 }
13438
13439 if( channelList )
13440 vos_mem_free( channelList );
13441
13442 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013443 return status;
13444}
13445
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013446int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13447#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13448 struct net_device *dev,
13449#endif
13450 struct cfg80211_scan_request *request)
13451{
13452 int ret;
13453
13454 vos_ssr_protect(__func__);
13455 ret = __wlan_hdd_cfg80211_scan(wiphy,
13456#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13457 dev,
13458#endif
13459 request);
13460 vos_ssr_unprotect(__func__);
13461
13462 return ret;
13463}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013464
13465void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13466{
13467 v_U8_t iniDot11Mode =
13468 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13469 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13470
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013471 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13472 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013473 switch ( iniDot11Mode )
13474 {
13475 case eHDD_DOT11_MODE_AUTO:
13476 case eHDD_DOT11_MODE_11ac:
13477 case eHDD_DOT11_MODE_11ac_ONLY:
13478#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013479 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13480 sme_IsFeatureSupportedByFW(DOT11AC) )
13481 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13482 else
13483 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013484#else
13485 hddDot11Mode = eHDD_DOT11_MODE_11n;
13486#endif
13487 break;
13488 case eHDD_DOT11_MODE_11n:
13489 case eHDD_DOT11_MODE_11n_ONLY:
13490 hddDot11Mode = eHDD_DOT11_MODE_11n;
13491 break;
13492 default:
13493 hddDot11Mode = iniDot11Mode;
13494 break;
13495 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013496#ifdef WLAN_FEATURE_AP_HT40_24G
13497 if (operationChannel > SIR_11B_CHANNEL_END)
13498#endif
13499 {
13500 /* This call decides required channel bonding mode */
13501 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013502 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13503 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013504 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013505}
13506
Jeff Johnson295189b2012-06-20 16:38:30 -070013507/*
13508 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013509 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013510 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013511int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013512 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13513 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013514{
13515 int status = 0;
13516 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013517 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013518 v_U32_t roamId;
13519 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013520 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013521 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013522
13523 ENTER();
13524
13525 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013526 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13527
13528 status = wlan_hdd_validate_context(pHddCtx);
13529 if (status)
13530 {
Yue Mae36e3552014-03-05 17:06:20 -080013531 return status;
13532 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013533
Jeff Johnson295189b2012-06-20 16:38:30 -070013534 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13535 {
13536 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13537 return -EINVAL;
13538 }
13539
13540 pRoamProfile = &pWextState->roamProfile;
13541
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013542 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013543 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013544 hdd_station_ctx_t *pHddStaCtx;
13545 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013546
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013547 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13548
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013549 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013550 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13551 {
13552 /*QoS not enabled in cfg file*/
13553 pRoamProfile->uapsd_mask = 0;
13554 }
13555 else
13556 {
13557 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013558 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013559 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13560 }
13561
13562 pRoamProfile->SSIDs.numOfSSIDs = 1;
13563 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13564 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013565 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013566 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13567 ssid, ssid_len);
13568
13569 if (bssid)
13570 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013571 pValidBssid = bssid;
13572 }
13573 else if (bssid_hint)
13574 {
13575 pValidBssid = bssid_hint;
13576 }
13577 if (pValidBssid)
13578 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013579 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013580 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013581 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013582 /* Save BSSID in seperate variable as well, as RoamProfile
13583 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013584 case of join failure we should send valid BSSID to supplicant
13585 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013586 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013587 WNI_CFG_BSSID_LEN);
13588 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013589 else
13590 {
13591 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13592 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013593
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013594 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13595 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013596 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13597 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013598 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013599 /*set gen ie*/
13600 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13601 /*set auth*/
13602 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13603 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013604#ifdef FEATURE_WLAN_WAPI
13605 if (pAdapter->wapi_info.nWapiMode)
13606 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013607 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013608 switch (pAdapter->wapi_info.wapiAuthMode)
13609 {
13610 case WAPI_AUTH_MODE_PSK:
13611 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013612 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013613 pAdapter->wapi_info.wapiAuthMode);
13614 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13615 break;
13616 }
13617 case WAPI_AUTH_MODE_CERT:
13618 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013619 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013620 pAdapter->wapi_info.wapiAuthMode);
13621 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13622 break;
13623 }
13624 } // End of switch
13625 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13626 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13627 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013628 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013629 pRoamProfile->AuthType.numEntries = 1;
13630 pRoamProfile->EncryptionType.numEntries = 1;
13631 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13632 pRoamProfile->mcEncryptionType.numEntries = 1;
13633 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13634 }
13635 }
13636#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013637#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013638 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013639 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13640 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13641 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013642 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13643 sizeof (tSirGtkOffloadParams));
13644 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013645 }
13646#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013647 pRoamProfile->csrPersona = pAdapter->device_mode;
13648
Jeff Johnson32d95a32012-09-10 13:15:23 -070013649 if( operatingChannel )
13650 {
13651 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13652 pRoamProfile->ChannelInfo.numOfChannels = 1;
13653 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013654 else
13655 {
13656 pRoamProfile->ChannelInfo.ChannelList = NULL;
13657 pRoamProfile->ChannelInfo.numOfChannels = 0;
13658 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013659 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13660 {
13661 hdd_select_cbmode(pAdapter,operatingChannel);
13662 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013663
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013664 /*
13665 * Change conn_state to connecting before sme_RoamConnect(),
13666 * because sme_RoamConnect() has a direct path to call
13667 * hdd_smeRoamCallback(), which will change the conn_state
13668 * If direct path, conn_state will be accordingly changed
13669 * to NotConnected or Associated by either
13670 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13671 * in sme_RoamCallback()
13672 * if sme_RomConnect is to be queued,
13673 * Connecting state will remain until it is completed.
13674 * If connection state is not changed,
13675 * connection state will remain in eConnectionState_NotConnected state.
13676 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13677 * if conn state is eConnectionState_NotConnected.
13678 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13679 * informed of connect result indication which is an issue.
13680 */
13681
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013682 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13683 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013684 {
13685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013686 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013687 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13688 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013689 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013690 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013691 pAdapter->sessionId, pRoamProfile, &roamId);
13692
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013693 if ((eHAL_STATUS_SUCCESS != status) &&
13694 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13695 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013696
13697 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013698 hddLog(VOS_TRACE_LEVEL_ERROR,
13699 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13700 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013701 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013702 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013703 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013704 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013705
13706 pRoamProfile->ChannelInfo.ChannelList = NULL;
13707 pRoamProfile->ChannelInfo.numOfChannels = 0;
13708
Jeff Johnson295189b2012-06-20 16:38:30 -070013709 }
13710 else
13711 {
13712 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13713 return -EINVAL;
13714 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013715 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013716 return status;
13717}
13718
13719/*
13720 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
13721 * This function is used to set the authentication type (OPEN/SHARED).
13722 *
13723 */
13724static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
13725 enum nl80211_auth_type auth_type)
13726{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013727 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013728 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13729
13730 ENTER();
13731
13732 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013733 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070013734 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013735 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013736 hddLog(VOS_TRACE_LEVEL_INFO,
13737 "%s: set authentication type to AUTOSWITCH", __func__);
13738 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
13739 break;
13740
13741 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013742#ifdef WLAN_FEATURE_VOWIFI_11R
13743 case NL80211_AUTHTYPE_FT:
13744#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013745 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013746 "%s: set authentication type to OPEN", __func__);
13747 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
13748 break;
13749
13750 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013751 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013752 "%s: set authentication type to SHARED", __func__);
13753 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
13754 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013755#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013756 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013757 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013758 "%s: set authentication type to CCKM WPA", __func__);
13759 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
13760 break;
13761#endif
13762
13763
13764 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013765 hddLog(VOS_TRACE_LEVEL_ERROR,
13766 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013767 auth_type);
13768 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
13769 return -EINVAL;
13770 }
13771
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013772 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013773 pHddStaCtx->conn_info.authType;
13774 return 0;
13775}
13776
13777/*
13778 * FUNCTION: wlan_hdd_set_akm_suite
13779 * This function is used to set the key mgmt type(PSK/8021x).
13780 *
13781 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013782static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013783 u32 key_mgmt
13784 )
13785{
13786 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13787 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053013788 /* Should be in ieee802_11_defs.h */
13789#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
13790#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070013791 /*set key mgmt type*/
13792 switch(key_mgmt)
13793 {
13794 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053013795 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013796#ifdef WLAN_FEATURE_VOWIFI_11R
13797 case WLAN_AKM_SUITE_FT_PSK:
13798#endif
13799 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070013800 __func__);
13801 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
13802 break;
13803
13804 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053013805 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013806#ifdef WLAN_FEATURE_VOWIFI_11R
13807 case WLAN_AKM_SUITE_FT_8021X:
13808#endif
13809 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070013810 __func__);
13811 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13812 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013813#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013814#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
13815#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
13816 case WLAN_AKM_SUITE_CCKM:
13817 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
13818 __func__);
13819 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
13820 break;
13821#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070013822#ifndef WLAN_AKM_SUITE_OSEN
13823#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
13824 case WLAN_AKM_SUITE_OSEN:
13825 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
13826 __func__);
13827 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13828 break;
13829#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013830
13831 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013832 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013833 __func__, key_mgmt);
13834 return -EINVAL;
13835
13836 }
13837 return 0;
13838}
13839
13840/*
13841 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013842 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070013843 * (NONE/WEP40/WEP104/TKIP/CCMP).
13844 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013845static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
13846 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070013847 bool ucast
13848 )
13849{
13850 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013851 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013852 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13853
13854 ENTER();
13855
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013856 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013857 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013858 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070013859 __func__, cipher);
13860 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13861 }
13862 else
13863 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013864
Jeff Johnson295189b2012-06-20 16:38:30 -070013865 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013866 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013867 {
13868 case IW_AUTH_CIPHER_NONE:
13869 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13870 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013871
Jeff Johnson295189b2012-06-20 16:38:30 -070013872 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013873 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070013874 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013875
Jeff Johnson295189b2012-06-20 16:38:30 -070013876 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013877 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070013878 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013879
Jeff Johnson295189b2012-06-20 16:38:30 -070013880 case WLAN_CIPHER_SUITE_TKIP:
13881 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
13882 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013883
Jeff Johnson295189b2012-06-20 16:38:30 -070013884 case WLAN_CIPHER_SUITE_CCMP:
13885 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13886 break;
13887#ifdef FEATURE_WLAN_WAPI
13888 case WLAN_CIPHER_SUITE_SMS4:
13889 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
13890 break;
13891#endif
13892
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013893#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013894 case WLAN_CIPHER_SUITE_KRK:
13895 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
13896 break;
13897#endif
13898 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013899 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013900 __func__, cipher);
13901 return -EOPNOTSUPP;
13902 }
13903 }
13904
13905 if (ucast)
13906 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013907 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013908 __func__, encryptionType);
13909 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13910 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013911 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013912 encryptionType;
13913 }
13914 else
13915 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013916 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013917 __func__, encryptionType);
13918 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
13919 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
13920 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
13921 }
13922
13923 return 0;
13924}
13925
13926
13927/*
13928 * FUNCTION: wlan_hdd_cfg80211_set_ie
13929 * This function is used to parse WPA/RSN IE's.
13930 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013931int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013932#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13933 const u8 *ie,
13934#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013935 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013936#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013937 size_t ie_len
13938 )
13939{
13940 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013941#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13942 const u8 *genie = ie;
13943#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013944 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013945#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013946 v_U16_t remLen = ie_len;
13947#ifdef FEATURE_WLAN_WAPI
13948 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
13949 u16 *tmp;
13950 v_U16_t akmsuiteCount;
13951 int *akmlist;
13952#endif
13953 ENTER();
13954
13955 /* clear previous assocAddIE */
13956 pWextState->assocAddIE.length = 0;
13957 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013958 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013959
13960 while (remLen >= 2)
13961 {
13962 v_U16_t eLen = 0;
13963 v_U8_t elementId;
13964 elementId = *genie++;
13965 eLen = *genie++;
13966 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013967
Arif Hussain6d2a3322013-11-17 19:50:10 -080013968 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070013969 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013970
13971 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070013972 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013973 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013974 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 -070013975 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013976 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013977 "%s: Invalid WPA IE", __func__);
13978 return -EINVAL;
13979 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013980 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070013981 {
13982 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013983 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013984 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013985
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013986 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013987 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013988 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
13989 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013990 VOS_ASSERT(0);
13991 return -ENOMEM;
13992 }
13993 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13994 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13995 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013996
Jeff Johnson295189b2012-06-20 16:38:30 -070013997 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
13998 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13999 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14000 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014001 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
14002 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014003 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
14004 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14005 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
14006 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
14007 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
14008 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014009 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053014010 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070014011 {
14012 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014013 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014014 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014015
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014016 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014017 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014018 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14019 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014020 VOS_ASSERT(0);
14021 return -ENOMEM;
14022 }
14023 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P 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 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014030#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014031 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
14032 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014033 /*Consider WFD IE, only for P2P Client */
14034 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
14035 {
14036 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014037 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014038 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014039
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014040 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014041 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014042 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14043 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014044 VOS_ASSERT(0);
14045 return -ENOMEM;
14046 }
14047 // WFD IE is saved to Additional IE ; it should be accumulated to handle
14048 // WPS IE + P2P IE + WFD IE
14049 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14050 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014051
Jeff Johnson295189b2012-06-20 16:38:30 -070014052 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14053 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14054 }
14055#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014056 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014057 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014058 HS20_OUI_TYPE_SIZE)) )
14059 {
14060 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014061 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014062 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014063
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014064 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014065 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014066 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14067 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014068 VOS_ASSERT(0);
14069 return -ENOMEM;
14070 }
14071 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14072 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014073
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014074 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14075 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14076 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014077 /* Appending OSEN Information Element in Assiciation Request */
14078 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
14079 OSEN_OUI_TYPE_SIZE)) )
14080 {
14081 v_U16_t curAddIELen = pWextState->assocAddIE.length;
14082 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
14083 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014084
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014085 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014086 {
14087 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14088 "Need bigger buffer space");
14089 VOS_ASSERT(0);
14090 return -ENOMEM;
14091 }
14092 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14093 pWextState->assocAddIE.length += eLen + 2;
14094
14095 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
14096 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14097 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14098 }
14099
Abhishek Singh4322e622015-06-10 15:42:54 +053014100 /* Update only for WPA IE */
14101 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
14102 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014103
14104 /* populating as ADDIE in beacon frames */
14105 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014106 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014107 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
14108 {
14109 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14110 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
14111 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14112 {
14113 hddLog(LOGE,
14114 "Coldn't pass "
14115 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
14116 }
14117 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
14118 else
14119 hddLog(LOGE,
14120 "Could not pass on "
14121 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
14122
14123 /* IBSS mode doesn't contain params->proberesp_ies still
14124 beaconIE's need to be populated in probe response frames */
14125 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
14126 {
14127 u16 rem_probe_resp_ie_len = eLen + 2;
14128 u8 probe_rsp_ie_len[3] = {0};
14129 u8 counter = 0;
14130
14131 /* Check Probe Resp Length if it is greater then 255 then
14132 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
14133 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
14134 not able Store More then 255 bytes into One Variable */
14135
14136 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
14137 {
14138 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
14139 {
14140 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
14141 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
14142 }
14143 else
14144 {
14145 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
14146 rem_probe_resp_ie_len = 0;
14147 }
14148 }
14149
14150 rem_probe_resp_ie_len = 0;
14151
14152 if (probe_rsp_ie_len[0] > 0)
14153 {
14154 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14155 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
14156 (tANI_U8*)(genie - 2),
14157 probe_rsp_ie_len[0], NULL,
14158 eANI_BOOLEAN_FALSE)
14159 == eHAL_STATUS_FAILURE)
14160 {
14161 hddLog(LOGE,
14162 "Could not pass"
14163 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
14164 }
14165 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
14166 }
14167
14168 if (probe_rsp_ie_len[1] > 0)
14169 {
14170 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14171 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
14172 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14173 probe_rsp_ie_len[1], NULL,
14174 eANI_BOOLEAN_FALSE)
14175 == eHAL_STATUS_FAILURE)
14176 {
14177 hddLog(LOGE,
14178 "Could not pass"
14179 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14180 }
14181 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14182 }
14183
14184 if (probe_rsp_ie_len[2] > 0)
14185 {
14186 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14187 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14188 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14189 probe_rsp_ie_len[2], NULL,
14190 eANI_BOOLEAN_FALSE)
14191 == eHAL_STATUS_FAILURE)
14192 {
14193 hddLog(LOGE,
14194 "Could not pass"
14195 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14196 }
14197 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14198 }
14199
14200 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14201 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14202 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14203 {
14204 hddLog(LOGE,
14205 "Could not pass"
14206 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14207 }
14208 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014209 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014210 break;
14211 case DOT11F_EID_RSN:
14212 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14213 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14214 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14215 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14216 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14217 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014218
Abhishek Singhb16f3562016-01-20 11:08:32 +053014219 /* Appending extended capabilities with Interworking or
14220 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053014221 *
14222 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053014223 * interworkingService or bsstransition bit is set to 1.
14224 * Driver is only interested in interworkingService and
14225 * bsstransition capability from supplicant.
14226 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053014227 * required from supplicat, it needs to be handled while
14228 * sending Assoc Req in LIM.
14229 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014230 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014231 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014232 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014233 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014234 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014235
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014236 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014237 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014238 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14239 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014240 VOS_ASSERT(0);
14241 return -ENOMEM;
14242 }
14243 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14244 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014245
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014246 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14247 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14248 break;
14249 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014250#ifdef FEATURE_WLAN_WAPI
14251 case WLAN_EID_WAPI:
14252 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014253 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014254 pAdapter->wapi_info.nWapiMode);
14255 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014256 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014257 akmsuiteCount = WPA_GET_LE16(tmp);
14258 tmp = tmp + 1;
14259 akmlist = (int *)(tmp);
14260 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14261 {
14262 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14263 }
14264 else
14265 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014266 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014267 VOS_ASSERT(0);
14268 return -EINVAL;
14269 }
14270
14271 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14272 {
14273 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014274 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014275 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014276 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014277 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014278 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014279 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014280 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014281 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14282 }
14283 break;
14284#endif
14285 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014286 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014287 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014288 /* when Unknown IE is received we should break and continue
14289 * to the next IE in the buffer instead we were returning
14290 * so changing this to break */
14291 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014292 }
14293 genie += eLen;
14294 remLen -= eLen;
14295 }
14296 EXIT();
14297 return 0;
14298}
14299
14300/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014301 * FUNCTION: hdd_isWPAIEPresent
14302 * Parse the received IE to find the WPA IE
14303 *
14304 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014305static bool hdd_isWPAIEPresent(
14306#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14307 const u8 *ie,
14308#else
14309 u8 *ie,
14310#endif
14311 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014312{
14313 v_U8_t eLen = 0;
14314 v_U16_t remLen = ie_len;
14315 v_U8_t elementId = 0;
14316
14317 while (remLen >= 2)
14318 {
14319 elementId = *ie++;
14320 eLen = *ie++;
14321 remLen -= 2;
14322 if (eLen > remLen)
14323 {
14324 hddLog(VOS_TRACE_LEVEL_ERROR,
14325 "%s: IE length is wrong %d", __func__, eLen);
14326 return FALSE;
14327 }
14328 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14329 {
14330 /* OUI - 0x00 0X50 0XF2
14331 WPA Information Element - 0x01
14332 WPA version - 0x01*/
14333 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14334 return TRUE;
14335 }
14336 ie += eLen;
14337 remLen -= eLen;
14338 }
14339 return FALSE;
14340}
14341
14342/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014343 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014344 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014345 * parameters during connect operation.
14346 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014347int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014348 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014349 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014350{
14351 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014352 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014353 ENTER();
14354
14355 /*set wpa version*/
14356 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14357
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014358 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014359 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014360 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014361 {
14362 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14363 }
14364 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14365 {
14366 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14367 }
14368 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014369
14370 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014371 pWextState->wpaVersion);
14372
14373 /*set authentication type*/
14374 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14375
14376 if (0 > status)
14377 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014378 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014379 "%s: failed to set authentication type ", __func__);
14380 return status;
14381 }
14382
14383 /*set key mgmt type*/
14384 if (req->crypto.n_akm_suites)
14385 {
14386 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14387 if (0 > status)
14388 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014389 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014390 __func__);
14391 return status;
14392 }
14393 }
14394
14395 /*set pairwise cipher type*/
14396 if (req->crypto.n_ciphers_pairwise)
14397 {
14398 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14399 req->crypto.ciphers_pairwise[0], true);
14400 if (0 > status)
14401 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014402 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014403 "%s: failed to set unicast cipher type", __func__);
14404 return status;
14405 }
14406 }
14407 else
14408 {
14409 /*Reset previous cipher suite to none*/
14410 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14411 if (0 > status)
14412 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014413 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014414 "%s: failed to set unicast cipher type", __func__);
14415 return status;
14416 }
14417 }
14418
14419 /*set group cipher type*/
14420 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14421 false);
14422
14423 if (0 > status)
14424 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014425 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014426 __func__);
14427 return status;
14428 }
14429
Chet Lanctot186b5732013-03-18 10:26:30 -070014430#ifdef WLAN_FEATURE_11W
14431 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14432#endif
14433
Jeff Johnson295189b2012-06-20 16:38:30 -070014434 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14435 if (req->ie_len)
14436 {
14437 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14438 if ( 0 > status)
14439 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014440 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014441 __func__);
14442 return status;
14443 }
14444 }
14445
14446 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014447 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014448 {
14449 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14450 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14451 )
14452 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014453 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014454 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14455 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014456 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014457 __func__);
14458 return -EOPNOTSUPP;
14459 }
14460 else
14461 {
14462 u8 key_len = req->key_len;
14463 u8 key_idx = req->key_idx;
14464
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014465 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014466 && (CSR_MAX_NUM_KEY > key_idx)
14467 )
14468 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014469 hddLog(VOS_TRACE_LEVEL_INFO,
14470 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014471 __func__, key_idx, key_len);
14472 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014473 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014474 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014475 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014476 (u8)key_len;
14477 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14478 }
14479 }
14480 }
14481 }
14482
14483 return status;
14484}
14485
14486/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014487 * FUNCTION: wlan_hdd_try_disconnect
14488 * This function is used to disconnect from previous
14489 * connection
14490 */
14491static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14492{
14493 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014494 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014495 hdd_station_ctx_t *pHddStaCtx;
14496 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014497 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014498
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014499 ret = wlan_hdd_validate_context(pHddCtx);
14500 if (0 != ret)
14501 {
14502 return ret;
14503 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014504 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14505
14506 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14507
14508 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14509 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053014510 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014511 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14512 {
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014513 spin_lock_bh(&pAdapter->lock_for_active_session);
14514 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14515 {
14516 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14517 }
14518 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053014519 hdd_connSetConnectionState(pHddStaCtx,
14520 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014521 /* Issue disconnect to CSR */
14522 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014523 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014524 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014525 eCSR_DISCONNECT_REASON_UNSPECIFIED);
14526 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
14527 hddLog(LOG1,
14528 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
14529 } else if ( 0 != status ) {
14530 hddLog(LOGE,
14531 FL("csrRoamDisconnect failure, returned %d"),
14532 (int)status );
14533 result = -EINVAL;
14534 goto disconnected;
14535 }
14536 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014537 &pAdapter->disconnect_comp_var,
14538 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014539 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
14540 hddLog(LOGE,
14541 "%s: Failed to disconnect, timed out", __func__);
14542 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014543 }
14544 }
14545 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14546 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014547 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014548 &pAdapter->disconnect_comp_var,
14549 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014550 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014551 {
14552 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014553 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014554 }
14555 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014556disconnected:
14557 hddLog(LOG1,
14558 FL("Set HDD connState to eConnectionState_NotConnected"));
14559 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14560 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014561}
14562
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014563/**
14564 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
14565 * @adapter: Pointer to the HDD adapter
14566 * @req: Pointer to the structure cfg_connect_params receieved from user space
14567 *
14568 * This function will start reassociation if bssid hint, channel hint and
14569 * previous bssid parameters are present in the connect request
14570 *
14571 * Return: success if reassociation is happening
14572 * Error code if reassociation is not permitted or not happening
14573 */
14574#ifdef CFG80211_CONNECT_PREV_BSSID
14575static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14576 struct cfg80211_connect_params *req)
14577{
14578 int status = -EPERM;
14579 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
14580 hddLog(VOS_TRACE_LEVEL_INFO,
14581 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
14582 req->channel_hint->hw_value,
14583 MAC_ADDR_ARRAY(req->bssid_hint));
14584 status = hdd_reassoc(adapter, req->bssid_hint,
14585 req->channel_hint->hw_value,
14586 CONNECT_CMD_USERSPACE);
14587 }
14588 return status;
14589}
14590#else
14591static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14592 struct cfg80211_connect_params *req)
14593{
14594 return -EPERM;
14595}
14596#endif
14597
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014598/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014599 * FUNCTION: __wlan_hdd_cfg80211_connect
14600 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014601 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014602static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014603 struct net_device *ndev,
14604 struct cfg80211_connect_params *req
14605 )
14606{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014607 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014608 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053014609#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
14610 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014611 const u8 *bssid_hint = req->bssid_hint;
14612#else
14613 const u8 *bssid_hint = NULL;
14614#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014615 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014616 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014617 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014618
14619 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014620
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014621 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14622 TRACE_CODE_HDD_CFG80211_CONNECT,
14623 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014624 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014625 "%s: device_mode = %s (%d)", __func__,
14626 hdd_device_modetoString(pAdapter->device_mode),
14627 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014628
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014629 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014630 if (!pHddCtx)
14631 {
14632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14633 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014634 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014635 }
14636
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014637 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014638 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014639 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014640 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014641 }
14642
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014643 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
14644 if (0 == status)
14645 return status;
14646
Agarwal Ashish51325b52014-06-16 16:50:49 +053014647
Jeff Johnson295189b2012-06-20 16:38:30 -070014648#ifdef WLAN_BTAMP_FEATURE
14649 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014650 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014651 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014652 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014653 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014654 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014655 }
14656#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014657
14658 //If Device Mode is Station Concurrent Sessions Exit BMps
14659 //P2P Mode will be taken care in Open/close adapter
14660 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014661 (vos_concurrent_open_sessions_running())) {
14662 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14663 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014664 }
14665
14666 /*Try disconnecting if already in connected state*/
14667 status = wlan_hdd_try_disconnect(pAdapter);
14668 if ( 0 > status)
14669 {
14670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14671 " connection"));
14672 return -EALREADY;
14673 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053014674 /* Check for max concurrent connections after doing disconnect if any*/
14675 if (vos_max_concurrent_connections_reached()) {
14676 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14677 return -ECONNREFUSED;
14678 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014679
Jeff Johnson295189b2012-06-20 16:38:30 -070014680 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014681 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014682
14683 if ( 0 > status)
14684 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014685 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014686 __func__);
14687 return status;
14688 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053014689
14690 if (pHddCtx->spoofMacAddr.isEnabled)
14691 {
14692 hddLog(VOS_TRACE_LEVEL_INFO,
14693 "%s: MAC Spoofing enabled ", __func__);
14694 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14695 * to fill TxBds for probe request during SSID scan which may happen
14696 * as part of connect command
14697 */
14698 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
14699 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
14700 if (status != VOS_STATUS_SUCCESS)
14701 return -ECONNREFUSED;
14702 }
14703
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014704 if (req->channel)
14705 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070014706 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014707 channel = 0;
14708 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14709 req->ssid_len, req->bssid,
14710 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014711
Sushant Kaushikd7083982015-03-18 14:33:24 +053014712 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014713 {
14714 //ReEnable BMPS if disabled
14715 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
14716 (NULL != pHddCtx))
14717 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053014718 if (pHddCtx->hdd_wlan_suspended)
14719 {
14720 hdd_set_pwrparams(pHddCtx);
14721 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014722 //ReEnable Bmps and Imps back
14723 hdd_enable_bmps_imps(pHddCtx);
14724 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070014726 return status;
14727 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014728 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014729 EXIT();
14730 return status;
14731}
14732
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014733static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
14734 struct net_device *ndev,
14735 struct cfg80211_connect_params *req)
14736{
14737 int ret;
14738 vos_ssr_protect(__func__);
14739 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
14740 vos_ssr_unprotect(__func__);
14741
14742 return ret;
14743}
Jeff Johnson295189b2012-06-20 16:38:30 -070014744
14745/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014746 * FUNCTION: wlan_hdd_disconnect
14747 * This function is used to issue a disconnect request to SME
14748 */
14749int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
14750{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014751 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014752 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014753 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014754 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014755
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014756 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014757
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014758 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014759 if (0 != status)
14760 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014761 return status;
14762 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053014763 /* Indicate sme of disconnect so that in progress connection or preauth
14764 * can be aborted
14765 */
14766 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053014767 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014768 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014769
Agarwal Ashish47d18112014-08-04 19:55:07 +053014770 /* Need to apply spin lock before decreasing active sessions
14771 * as there can be chance for double decrement if context switch
14772 * Calls hdd_DisConnectHandler.
14773 */
14774
14775 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014776 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14777 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014778 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14779 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053014780 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
14781 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014782
Abhishek Singhf4669da2014-05-26 15:07:49 +053014783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053014784 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
14785
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014786 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014787
Mihir Shete182a0b22014-08-18 16:08:48 +053014788 /*
14789 * stop tx queues before deleting STA/BSS context from the firmware.
14790 * tx has to be disabled because the firmware can get busy dropping
14791 * the tx frames after BSS/STA has been deleted and will not send
14792 * back a response resulting in WDI timeout
14793 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053014794 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053014795 netif_tx_disable(pAdapter->dev);
14796 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014797
Mihir Shete182a0b22014-08-18 16:08:48 +053014798 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014799 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14800 pAdapter->sessionId, reason);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014801 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
14802 {
14803 hddLog(LOG1,
14804 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014805 }
14806 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014807 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014808 hddLog(LOGE,
14809 FL("csrRoamDisconnect failure, returned %d"),
14810 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014811 result = -EINVAL;
14812 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014813 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014814 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014815 &pAdapter->disconnect_comp_var,
14816 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014817 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014818 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014819 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014820 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014821 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014822 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014823disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014824 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014825 FL("Set HDD connState to eConnectionState_NotConnected"));
14826 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053014827#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
14828 /* Sending disconnect event to userspace for kernel version < 3.11
14829 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
14830 */
14831 hddLog(LOG1, FL("Send disconnected event to userspace"));
14832
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053014833 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053014834 WLAN_REASON_UNSPECIFIED);
14835#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014836
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014837 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014838 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014839}
14840
14841
14842/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014843 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070014844 * This function is used to issue a disconnect request to SME
14845 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014846static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014847 struct net_device *dev,
14848 u16 reason
14849 )
14850{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014851 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014852 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014853 tCsrRoamProfile *pRoamProfile;
14854 hdd_station_ctx_t *pHddStaCtx;
14855 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014856#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014857 tANI_U8 staIdx;
14858#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014859
Jeff Johnson295189b2012-06-20 16:38:30 -070014860 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014861
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014862 if (!pAdapter) {
14863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14864 return -EINVAL;
14865 }
14866
14867 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14868 if (!pHddStaCtx) {
14869 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
14870 return -EINVAL;
14871 }
14872
14873 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14874 status = wlan_hdd_validate_context(pHddCtx);
14875 if (0 != status)
14876 {
14877 return status;
14878 }
14879
14880 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
14881
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014882 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14883 TRACE_CODE_HDD_CFG80211_DISCONNECT,
14884 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014885 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
14886 __func__, hdd_device_modetoString(pAdapter->device_mode),
14887 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014888
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014889 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
14890 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070014891
Jeff Johnson295189b2012-06-20 16:38:30 -070014892 if (NULL != pRoamProfile)
14893 {
14894 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014895 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
14896 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070014897 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014898 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070014899 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014900 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014901 switch(reason)
14902 {
14903 case WLAN_REASON_MIC_FAILURE:
14904 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
14905 break;
14906
14907 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
14908 case WLAN_REASON_DISASSOC_AP_BUSY:
14909 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
14910 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
14911 break;
14912
14913 case WLAN_REASON_PREV_AUTH_NOT_VALID:
14914 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053014915 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070014916 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
14917 break;
14918
Jeff Johnson295189b2012-06-20 16:38:30 -070014919 default:
14920 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
14921 break;
14922 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014923 pScanInfo = &pHddCtx->scan_info;
14924 if (pScanInfo->mScanPending)
14925 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014926 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014927 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014928 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014929 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014930 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053014931 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014932#ifdef FEATURE_WLAN_TDLS
14933 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014934 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014935 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014936 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
14937 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014938 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014939 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014940 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014942 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014943 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014944 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014945 status = sme_DeleteTdlsPeerSta(
14946 WLAN_HDD_GET_HAL_CTX(pAdapter),
14947 pAdapter->sessionId,
14948 mac);
14949 if (status != eHAL_STATUS_SUCCESS) {
14950 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
14951 return -EPERM;
14952 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014953 }
14954 }
14955#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014956 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014957 status = wlan_hdd_disconnect(pAdapter, reasonCode);
14958 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070014959 {
14960 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014961 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014962 __func__, (int)status );
14963 return -EINVAL;
14964 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014965 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014966 else
14967 {
14968 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
14969 "called while in %d state", __func__,
14970 pHddStaCtx->conn_info.connState);
14971 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014972 }
14973 else
14974 {
14975 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
14976 }
14977
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014978 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014979 return status;
14980}
14981
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014982static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
14983 struct net_device *dev,
14984 u16 reason
14985 )
14986{
14987 int ret;
14988 vos_ssr_protect(__func__);
14989 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
14990 vos_ssr_unprotect(__func__);
14991
14992 return ret;
14993}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014994
Jeff Johnson295189b2012-06-20 16:38:30 -070014995/*
14996 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014997 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014998 * settings in IBSS mode.
14999 */
15000static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015001 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015002 struct cfg80211_ibss_params *params
15003 )
15004{
15005 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015006 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015007 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15008 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015009
Jeff Johnson295189b2012-06-20 16:38:30 -070015010 ENTER();
15011
15012 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070015013 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070015014
15015 if (params->ie_len && ( NULL != params->ie) )
15016 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015017 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15018 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015019 {
15020 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15021 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15022 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015023 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015024 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015025 tDot11fIEWPA dot11WPAIE;
15026 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015027 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015028
Wilson Yang00256342013-10-10 23:13:38 -070015029 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015030 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15031 params->ie_len, DOT11F_EID_WPA);
15032 if ( NULL != ie )
15033 {
15034 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15035 // Unpack the WPA IE
15036 //Skip past the EID byte and length byte - and four byte WiFi OUI
15037 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
15038 &ie[2+4],
15039 ie[1] - 4,
15040 &dot11WPAIE);
15041 /*Extract the multicast cipher, the encType for unicast
15042 cipher for wpa-none is none*/
15043 encryptionType =
15044 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
15045 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015046 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015047
Jeff Johnson295189b2012-06-20 16:38:30 -070015048 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
15049
15050 if (0 > status)
15051 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015052 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015053 __func__);
15054 return status;
15055 }
15056 }
15057
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015058 pWextState->roamProfile.AuthType.authType[0] =
15059 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070015060 eCSR_AUTH_TYPE_OPEN_SYSTEM;
15061
15062 if (params->privacy)
15063 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015064 /* Security enabled IBSS, At this time there is no information available
15065 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070015066 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015067 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070015068 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015069 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070015070 *enable privacy bit in beacons */
15071
15072 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
15073 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015074 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
15075 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070015076 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15077 pWextState->roamProfile.EncryptionType.numEntries = 1;
15078 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070015079 return status;
15080}
15081
15082/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015083 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015084 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015085 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015086static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015087 struct net_device *dev,
15088 struct cfg80211_ibss_params *params
15089 )
15090{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015091 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015092 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15093 tCsrRoamProfile *pRoamProfile;
15094 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015095 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15096 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015097 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070015098
15099 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015100
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015101 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15102 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
15103 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015104 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015105 "%s: device_mode = %s (%d)", __func__,
15106 hdd_device_modetoString(pAdapter->device_mode),
15107 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015108
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015109 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015110 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015111 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015112 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015113 }
15114
15115 if (NULL == pWextState)
15116 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015117 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015118 __func__);
15119 return -EIO;
15120 }
15121
Agarwal Ashish51325b52014-06-16 16:50:49 +053015122 if (vos_max_concurrent_connections_reached()) {
15123 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15124 return -ECONNREFUSED;
15125 }
15126
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015127 /*Try disconnecting if already in connected state*/
15128 status = wlan_hdd_try_disconnect(pAdapter);
15129 if ( 0 > status)
15130 {
15131 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15132 " IBSS connection"));
15133 return -EALREADY;
15134 }
15135
Jeff Johnson295189b2012-06-20 16:38:30 -070015136 pRoamProfile = &pWextState->roamProfile;
15137
15138 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
15139 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015140 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015141 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015142 return -EINVAL;
15143 }
15144
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015145 /* BSSID is provided by upper layers hence no need to AUTO generate */
15146 if (NULL != params->bssid) {
15147 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15148 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
15149 hddLog (VOS_TRACE_LEVEL_ERROR,
15150 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15151 return -EIO;
15152 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015153 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015154 }
krunal sonie9002db2013-11-25 14:24:17 -080015155 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
15156 {
15157 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15158 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
15159 {
15160 hddLog (VOS_TRACE_LEVEL_ERROR,
15161 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15162 return -EIO;
15163 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015164
15165 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080015166 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015167 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080015168 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015169
Jeff Johnson295189b2012-06-20 16:38:30 -070015170 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070015171 if (NULL !=
15172#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15173 params->chandef.chan)
15174#else
15175 params->channel)
15176#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015177 {
15178 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015179 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15180 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
15181 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15182 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015183
15184 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015185 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070015186 ieee80211_frequency_to_channel(
15187#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15188 params->chandef.chan->center_freq);
15189#else
15190 params->channel->center_freq);
15191#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015192
15193 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15194 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070015195 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015196 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
15197 __func__);
15198 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070015199 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015200
15201 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015202 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015203 if (channelNum == validChan[indx])
15204 {
15205 break;
15206 }
15207 }
15208 if (indx >= numChans)
15209 {
15210 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015211 __func__, channelNum);
15212 return -EINVAL;
15213 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015214 /* Set the Operational Channel */
15215 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
15216 channelNum);
15217 pRoamProfile->ChannelInfo.numOfChannels = 1;
15218 pHddStaCtx->conn_info.operationChannel = channelNum;
15219 pRoamProfile->ChannelInfo.ChannelList =
15220 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070015221 }
15222
15223 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015224 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070015225 if (status < 0)
15226 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015227 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070015228 __func__);
15229 return status;
15230 }
15231
15232 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015233 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053015234 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015235 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015236
15237 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015238 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015239
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015240 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015241 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015242}
15243
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015244static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
15245 struct net_device *dev,
15246 struct cfg80211_ibss_params *params
15247 )
15248{
15249 int ret = 0;
15250
15251 vos_ssr_protect(__func__);
15252 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15253 vos_ssr_unprotect(__func__);
15254
15255 return ret;
15256}
15257
Jeff Johnson295189b2012-06-20 16:38:30 -070015258/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015259 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015260 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015261 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015262static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015263 struct net_device *dev
15264 )
15265{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015266 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015267 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15268 tCsrRoamProfile *pRoamProfile;
15269 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015270 int status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015271#ifdef WLAN_FEATURE_RMC
15272 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
15273#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015274
15275 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015276
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015277 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15278 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15279 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015280 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015281 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015282 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015283 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015284 }
15285
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015286 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15287 hdd_device_modetoString(pAdapter->device_mode),
15288 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015289 if (NULL == pWextState)
15290 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015291 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015292 __func__);
15293 return -EIO;
15294 }
15295
15296 pRoamProfile = &pWextState->roamProfile;
15297
15298 /* Issue disconnect only if interface type is set to IBSS */
15299 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15300 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015301 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015302 __func__);
15303 return -EINVAL;
15304 }
15305
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015306#ifdef WLAN_FEATURE_RMC
15307 /* Clearing add IE of beacon */
15308 if (ccmCfgSetStr(pHddCtx->hHal,
15309 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
15310 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
15311 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15312 {
15313 hddLog (VOS_TRACE_LEVEL_ERROR,
15314 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
15315 return -EINVAL;
15316 }
15317 if (ccmCfgSetInt(pHddCtx->hHal,
15318 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
15319 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15320 {
15321 hddLog (VOS_TRACE_LEVEL_ERROR,
15322 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
15323 __func__);
15324 return -EINVAL;
15325 }
15326
15327 // Reset WNI_CFG_PROBE_RSP Flags
15328 wlan_hdd_reset_prob_rspies(pAdapter);
15329
15330 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15331 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
15332 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15333 {
15334 hddLog (VOS_TRACE_LEVEL_ERROR,
15335 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
15336 __func__);
15337 return -EINVAL;
15338 }
15339#endif
15340
Jeff Johnson295189b2012-06-20 16:38:30 -070015341 /* Issue Disconnect request */
15342 INIT_COMPLETION(pAdapter->disconnect_comp_var);
15343 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15344 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15345
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015346 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015347 return 0;
15348}
15349
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015350static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15351 struct net_device *dev
15352 )
15353{
15354 int ret = 0;
15355
15356 vos_ssr_protect(__func__);
15357 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15358 vos_ssr_unprotect(__func__);
15359
15360 return ret;
15361}
15362
Jeff Johnson295189b2012-06-20 16:38:30 -070015363/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015364 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015365 * This function is used to set the phy parameters
15366 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15367 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015368static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015369 u32 changed)
15370{
15371 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15372 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015373 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015374
15375 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015376
15377 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015378 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15379 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015380
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015381 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015382 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015383 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015384 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015385 }
15386
Jeff Johnson295189b2012-06-20 16:38:30 -070015387 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15388 {
15389 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15390 WNI_CFG_RTS_THRESHOLD_STAMAX :
15391 wiphy->rts_threshold;
15392
15393 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015394 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015395 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015396 hddLog(VOS_TRACE_LEVEL_ERROR,
15397 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015398 __func__, rts_threshold);
15399 return -EINVAL;
15400 }
15401
15402 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15403 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015404 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015405 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015406 hddLog(VOS_TRACE_LEVEL_ERROR,
15407 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015408 __func__, rts_threshold);
15409 return -EIO;
15410 }
15411
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015412 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015413 rts_threshold);
15414 }
15415
15416 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15417 {
15418 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15419 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15420 wiphy->frag_threshold;
15421
15422 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015423 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015424 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015425 hddLog(VOS_TRACE_LEVEL_ERROR,
15426 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015427 frag_threshold);
15428 return -EINVAL;
15429 }
15430
15431 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15432 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015433 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015434 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015435 hddLog(VOS_TRACE_LEVEL_ERROR,
15436 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015437 __func__, frag_threshold);
15438 return -EIO;
15439 }
15440
15441 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15442 frag_threshold);
15443 }
15444
15445 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15446 || (changed & WIPHY_PARAM_RETRY_LONG))
15447 {
15448 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15449 wiphy->retry_short :
15450 wiphy->retry_long;
15451
15452 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15453 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15454 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015455 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015456 __func__, retry_value);
15457 return -EINVAL;
15458 }
15459
15460 if (changed & WIPHY_PARAM_RETRY_SHORT)
15461 {
15462 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15463 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015464 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015465 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015466 hddLog(VOS_TRACE_LEVEL_ERROR,
15467 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015468 __func__, retry_value);
15469 return -EIO;
15470 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015471 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015472 __func__, retry_value);
15473 }
15474 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15475 {
15476 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15477 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015478 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015479 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015480 hddLog(VOS_TRACE_LEVEL_ERROR,
15481 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015482 __func__, retry_value);
15483 return -EIO;
15484 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015485 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015486 __func__, retry_value);
15487 }
15488 }
15489
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015490 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015491 return 0;
15492}
15493
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015494static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15495 u32 changed)
15496{
15497 int ret;
15498
15499 vos_ssr_protect(__func__);
15500 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15501 vos_ssr_unprotect(__func__);
15502
15503 return ret;
15504}
15505
Jeff Johnson295189b2012-06-20 16:38:30 -070015506/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015507 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015508 * This function is used to set the txpower
15509 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015510static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015511#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15512 struct wireless_dev *wdev,
15513#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015514#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015515 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015516#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015517 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015518#endif
15519 int dbm)
15520{
15521 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015522 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015523 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15524 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015525 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015526
15527 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015528
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015529 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15530 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15531 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015532 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015533 if (0 != status)
15534 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015535 return status;
15536 }
15537
15538 hHal = pHddCtx->hHal;
15539
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015540 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15541 dbm, ccmCfgSetCallback,
15542 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015543 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015544 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015545 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15546 return -EIO;
15547 }
15548
15549 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15550 dbm);
15551
15552 switch(type)
15553 {
15554 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15555 /* Fall through */
15556 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15557 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15558 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015559 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15560 __func__);
15561 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015562 }
15563 break;
15564 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015565 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015566 __func__);
15567 return -EOPNOTSUPP;
15568 break;
15569 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015570 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15571 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015572 return -EIO;
15573 }
15574
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015575 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015576 return 0;
15577}
15578
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015579static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15580#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15581 struct wireless_dev *wdev,
15582#endif
15583#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15584 enum tx_power_setting type,
15585#else
15586 enum nl80211_tx_power_setting type,
15587#endif
15588 int dbm)
15589{
15590 int ret;
15591 vos_ssr_protect(__func__);
15592 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15593#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15594 wdev,
15595#endif
15596#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15597 type,
15598#else
15599 type,
15600#endif
15601 dbm);
15602 vos_ssr_unprotect(__func__);
15603
15604 return ret;
15605}
15606
Jeff Johnson295189b2012-06-20 16:38:30 -070015607/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015608 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015609 * This function is used to read the txpower
15610 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015611static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015612#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15613 struct wireless_dev *wdev,
15614#endif
15615 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015616{
15617
15618 hdd_adapter_t *pAdapter;
15619 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015620 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015621
Jeff Johnsone7245742012-09-05 17:12:55 -070015622 ENTER();
15623
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015624 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015625 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015626 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015627 *dbm = 0;
15628 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015629 }
15630
Jeff Johnson295189b2012-06-20 16:38:30 -070015631 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15632 if (NULL == pAdapter)
15633 {
15634 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15635 return -ENOENT;
15636 }
15637
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015638 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15639 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15640 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015641 wlan_hdd_get_classAstats(pAdapter);
15642 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15643
Jeff Johnsone7245742012-09-05 17:12:55 -070015644 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015645 return 0;
15646}
15647
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015648static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15649#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15650 struct wireless_dev *wdev,
15651#endif
15652 int *dbm)
15653{
15654 int ret;
15655
15656 vos_ssr_protect(__func__);
15657 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15658#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15659 wdev,
15660#endif
15661 dbm);
15662 vos_ssr_unprotect(__func__);
15663
15664 return ret;
15665}
15666
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015667static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015668#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15669 const u8* mac,
15670#else
15671 u8* mac,
15672#endif
15673 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015674{
15675 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15676 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15677 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053015678 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015679
15680 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
15681 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070015682
15683 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
15684 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
15685 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
15686 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
15687 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
15688 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
15689 tANI_U16 maxRate = 0;
15690 tANI_U16 myRate;
15691 tANI_U16 currentRate = 0;
15692 tANI_U8 maxSpeedMCS = 0;
15693 tANI_U8 maxMCSIdx = 0;
15694 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053015695 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070015696 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015697 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015698
Leo Chang6f8870f2013-03-26 18:11:36 -070015699#ifdef WLAN_FEATURE_11AC
15700 tANI_U32 vht_mcs_map;
15701 eDataRate11ACMaxMcs vhtMaxMcs;
15702#endif /* WLAN_FEATURE_11AC */
15703
Jeff Johnsone7245742012-09-05 17:12:55 -070015704 ENTER();
15705
Jeff Johnson295189b2012-06-20 16:38:30 -070015706 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15707 (0 == ssidlen))
15708 {
15709 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
15710 " Invalid ssidlen, %d", __func__, ssidlen);
15711 /*To keep GUI happy*/
15712 return 0;
15713 }
15714
Mukul Sharma811205f2014-07-09 21:07:30 +053015715 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
15716 {
15717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15718 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053015719 /* return a cached value */
15720 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053015721 return 0;
15722 }
15723
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015724 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015725 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015726 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015727 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015728 }
15729
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053015730 wlan_hdd_get_station_stats(pAdapter);
15731 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015732
Kiet Lam3b17fc82013-09-27 05:24:08 +053015733 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
15734 sinfo->filled |= STATION_INFO_SIGNAL;
15735
c_hpothu09f19542014-05-30 21:53:31 +053015736 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053015737 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
15738 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053015739 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053015740 {
15741 rate_flags = pAdapter->maxRateFlags;
15742 }
c_hpothu44ff4e02014-05-08 00:13:57 +053015743
Jeff Johnson295189b2012-06-20 16:38:30 -070015744 //convert to the UI units of 100kbps
15745 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
15746
15747#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070015748 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 -070015749 sinfo->signal,
15750 pCfg->reportMaxLinkSpeed,
15751 myRate,
15752 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015753 (int) pCfg->linkSpeedRssiMid,
15754 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070015755 (int) rate_flags,
15756 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070015757#endif //LINKSPEED_DEBUG_ENABLED
15758
15759 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
15760 {
15761 // we do not want to necessarily report the current speed
15762 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
15763 {
15764 // report the max possible speed
15765 rssidx = 0;
15766 }
15767 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
15768 {
15769 // report the max possible speed with RSSI scaling
15770 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
15771 {
15772 // report the max possible speed
15773 rssidx = 0;
15774 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015775 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070015776 {
15777 // report middle speed
15778 rssidx = 1;
15779 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015780 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
15781 {
15782 // report middle speed
15783 rssidx = 2;
15784 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015785 else
15786 {
15787 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015788 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070015789 }
15790 }
15791 else
15792 {
15793 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
15794 hddLog(VOS_TRACE_LEVEL_ERROR,
15795 "%s: Invalid value for reportMaxLinkSpeed: %u",
15796 __func__, pCfg->reportMaxLinkSpeed);
15797 rssidx = 0;
15798 }
15799
15800 maxRate = 0;
15801
15802 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015803 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
15804 OperationalRates, &ORLeng))
15805 {
15806 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15807 /*To keep GUI happy*/
15808 return 0;
15809 }
15810
Jeff Johnson295189b2012-06-20 16:38:30 -070015811 for (i = 0; i < ORLeng; i++)
15812 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015813 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015814 {
15815 /* Validate Rate Set */
15816 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
15817 {
15818 currentRate = supported_data_rate[j].supported_rate[rssidx];
15819 break;
15820 }
15821 }
15822 /* Update MAX rate */
15823 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15824 }
15825
15826 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015827 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
15828 ExtendedRates, &ERLeng))
15829 {
15830 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15831 /*To keep GUI happy*/
15832 return 0;
15833 }
15834
Jeff Johnson295189b2012-06-20 16:38:30 -070015835 for (i = 0; i < ERLeng; i++)
15836 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015837 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015838 {
15839 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
15840 {
15841 currentRate = supported_data_rate[j].supported_rate[rssidx];
15842 break;
15843 }
15844 }
15845 /* Update MAX rate */
15846 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15847 }
c_hpothu79aab322014-07-14 21:11:01 +053015848
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015849 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053015850 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015851 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053015852 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070015853 {
c_hpothu79aab322014-07-14 21:11:01 +053015854 if (rate_flags & eHAL_TX_RATE_VHT80)
15855 mode = 2;
15856 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
15857 mode = 1;
15858 else
15859 mode = 0;
15860
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015861 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
15862 MCSRates, &MCSLeng))
15863 {
15864 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15865 /*To keep GUI happy*/
15866 return 0;
15867 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015868 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070015869#ifdef WLAN_FEATURE_11AC
15870 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015871 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070015872 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015873 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015874 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070015875 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070015876 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015877 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015878 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015879 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070015880 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015881 maxMCSIdx = 7;
15882 }
15883 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
15884 {
15885 maxMCSIdx = 8;
15886 }
15887 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
15888 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015889 //VHT20 is supporting 0~8
15890 if (rate_flags & eHAL_TX_RATE_VHT20)
15891 maxMCSIdx = 8;
15892 else
15893 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070015894 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015895
c_hpothu79aab322014-07-14 21:11:01 +053015896 if (0 != rssidx)/*check for scaled */
15897 {
15898 //get middle rate MCS index if rssi=1/2
15899 for (i=0; i <= maxMCSIdx; i++)
15900 {
15901 if (sinfo->signal <= rssiMcsTbl[mode][i])
15902 {
15903 maxMCSIdx = i;
15904 break;
15905 }
15906 }
15907 }
15908
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015909 if (rate_flags & eHAL_TX_RATE_VHT80)
15910 {
15911 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
15912 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
15913 }
15914 else if (rate_flags & eHAL_TX_RATE_VHT40)
15915 {
15916 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
15917 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
15918 }
15919 else if (rate_flags & eHAL_TX_RATE_VHT20)
15920 {
15921 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
15922 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
15923 }
15924
Leo Chang6f8870f2013-03-26 18:11:36 -070015925 maxSpeedMCS = 1;
15926 if (currentRate > maxRate)
15927 {
15928 maxRate = currentRate;
15929 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015930
Leo Chang6f8870f2013-03-26 18:11:36 -070015931 }
15932 else
15933#endif /* WLAN_FEATURE_11AC */
15934 {
15935 if (rate_flags & eHAL_TX_RATE_HT40)
15936 {
15937 rateFlag |= 1;
15938 }
15939 if (rate_flags & eHAL_TX_RATE_SGI)
15940 {
15941 rateFlag |= 2;
15942 }
15943
Girish Gowli01abcee2014-07-31 20:18:55 +053015944 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053015945 if (rssidx == 1 || rssidx == 2)
15946 {
15947 //get middle rate MCS index if rssi=1/2
15948 for (i=0; i <= 7; i++)
15949 {
15950 if (sinfo->signal <= rssiMcsTbl[mode][i])
15951 {
15952 temp = i+1;
15953 break;
15954 }
15955 }
15956 }
c_hpothu79aab322014-07-14 21:11:01 +053015957
15958 for (i = 0; i < MCSLeng; i++)
15959 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015960 for (j = 0; j < temp; j++)
15961 {
15962 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
15963 {
15964 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015965 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015966 break;
15967 }
15968 }
15969 if ((j < temp) && (currentRate > maxRate))
15970 {
15971 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070015972 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015973 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015974 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015975 }
15976 }
15977
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015978 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
15979 {
15980 maxRate = myRate;
15981 maxSpeedMCS = 1;
15982 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15983 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015984 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053015985 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070015986 {
15987 maxRate = myRate;
15988 if (rate_flags & eHAL_TX_RATE_LEGACY)
15989 {
15990 maxSpeedMCS = 0;
15991 }
15992 else
15993 {
15994 maxSpeedMCS = 1;
15995 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15996 }
15997 }
15998
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015999 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070016000 {
16001 sinfo->txrate.legacy = maxRate;
16002#ifdef LINKSPEED_DEBUG_ENABLED
16003 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
16004#endif //LINKSPEED_DEBUG_ENABLED
16005 }
16006 else
16007 {
16008 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070016009#ifdef WLAN_FEATURE_11AC
16010 sinfo->txrate.nss = 1;
16011 if (rate_flags & eHAL_TX_RATE_VHT80)
16012 {
16013 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016014 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070016015 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016016 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070016017 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016018 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16019 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16020 }
16021 else if (rate_flags & eHAL_TX_RATE_VHT20)
16022 {
16023 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16024 }
16025#endif /* WLAN_FEATURE_11AC */
16026 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
16027 {
16028 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16029 if (rate_flags & eHAL_TX_RATE_HT40)
16030 {
16031 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16032 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016033 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016034 if (rate_flags & eHAL_TX_RATE_SGI)
16035 {
16036 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16037 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016038
Jeff Johnson295189b2012-06-20 16:38:30 -070016039#ifdef LINKSPEED_DEBUG_ENABLED
16040 pr_info("Reporting MCS rate %d flags %x\n",
16041 sinfo->txrate.mcs,
16042 sinfo->txrate.flags );
16043#endif //LINKSPEED_DEBUG_ENABLED
16044 }
16045 }
16046 else
16047 {
16048 // report current rate instead of max rate
16049
16050 if (rate_flags & eHAL_TX_RATE_LEGACY)
16051 {
16052 //provide to the UI in units of 100kbps
16053 sinfo->txrate.legacy = myRate;
16054#ifdef LINKSPEED_DEBUG_ENABLED
16055 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
16056#endif //LINKSPEED_DEBUG_ENABLED
16057 }
16058 else
16059 {
16060 //must be MCS
16061 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016062#ifdef WLAN_FEATURE_11AC
16063 sinfo->txrate.nss = 1;
16064 if (rate_flags & eHAL_TX_RATE_VHT80)
16065 {
16066 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16067 }
16068 else
16069#endif /* WLAN_FEATURE_11AC */
16070 {
16071 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16072 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016073 if (rate_flags & eHAL_TX_RATE_SGI)
16074 {
16075 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16076 }
16077 if (rate_flags & eHAL_TX_RATE_HT40)
16078 {
16079 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16080 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016081#ifdef WLAN_FEATURE_11AC
16082 else if (rate_flags & eHAL_TX_RATE_VHT80)
16083 {
16084 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
16085 }
16086#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070016087#ifdef LINKSPEED_DEBUG_ENABLED
16088 pr_info("Reporting actual MCS rate %d flags %x\n",
16089 sinfo->txrate.mcs,
16090 sinfo->txrate.flags );
16091#endif //LINKSPEED_DEBUG_ENABLED
16092 }
16093 }
16094 sinfo->filled |= STATION_INFO_TX_BITRATE;
16095
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016096 sinfo->tx_packets =
16097 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
16098 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
16099 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
16100 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
16101
16102 sinfo->tx_retries =
16103 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
16104 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
16105 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
16106 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
16107
16108 sinfo->tx_failed =
16109 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
16110 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
16111 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
16112 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
16113
16114 sinfo->filled |=
16115 STATION_INFO_TX_PACKETS |
16116 STATION_INFO_TX_RETRIES |
16117 STATION_INFO_TX_FAILED;
16118
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053016119 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
16120 sinfo->filled |= STATION_INFO_RX_PACKETS;
16121
16122 if (rate_flags & eHAL_TX_RATE_LEGACY)
16123 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
16124 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
16125 sinfo->rx_packets);
16126 else
16127 hddLog(LOG1,
16128 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
16129 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
16130 sinfo->tx_packets, sinfo->rx_packets);
16131
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016132 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16133 TRACE_CODE_HDD_CFG80211_GET_STA,
16134 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016135 EXIT();
16136 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016137}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016138#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16139static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16140 const u8* mac, struct station_info *sinfo)
16141#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016142static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16143 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016144#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016145{
16146 int ret;
16147
16148 vos_ssr_protect(__func__);
16149 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
16150 vos_ssr_unprotect(__func__);
16151
16152 return ret;
16153}
16154
16155static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070016156 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070016157{
16158 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016159 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016160 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016161 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016162
Jeff Johnsone7245742012-09-05 17:12:55 -070016163 ENTER();
16164
Jeff Johnson295189b2012-06-20 16:38:30 -070016165 if (NULL == pAdapter)
16166 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016167 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016168 return -ENODEV;
16169 }
16170
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016171 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16172 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
16173 pAdapter->sessionId, timeout));
16174
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016175 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016176 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016177 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016178 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016179 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016180 }
16181
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016182 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
16183 (TRUE == pHddCtx->hdd_wlan_suspended) &&
16184 (pHddCtx->cfg_ini->fhostArpOffload) &&
16185 (eConnectionState_Associated ==
16186 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
16187 {
Amar Singhald53568e2013-09-26 11:03:45 -070016188
16189 hddLog(VOS_TRACE_LEVEL_INFO,
16190 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053016191 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016192 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16193 {
16194 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016195 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016196 __func__, vos_status);
16197 }
16198 }
16199
Jeff Johnson295189b2012-06-20 16:38:30 -070016200 /**The get power cmd from the supplicant gets updated by the nl only
16201 *on successful execution of the function call
16202 *we are oppositely mapped w.r.t mode in the driver
16203 **/
16204 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
16205
16206 if (VOS_STATUS_E_FAILURE == vos_status)
16207 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16209 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016210 return -EINVAL;
16211 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016212 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016213 return 0;
16214}
16215
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016216static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
16217 struct net_device *dev, bool mode, int timeout)
16218{
16219 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016220
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016221 vos_ssr_protect(__func__);
16222 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
16223 vos_ssr_unprotect(__func__);
16224
16225 return ret;
16226}
Sushant Kaushik084f6592015-09-10 13:11:56 +053016227
Jeff Johnson295189b2012-06-20 16:38:30 -070016228#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016229static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
16230 struct net_device *netdev,
16231 u8 key_index)
16232{
16233 ENTER();
16234 return 0;
16235}
16236
Jeff Johnson295189b2012-06-20 16:38:30 -070016237static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016238 struct net_device *netdev,
16239 u8 key_index)
16240{
16241 int ret;
16242 vos_ssr_protect(__func__);
16243 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
16244 vos_ssr_unprotect(__func__);
16245 return ret;
16246}
16247#endif //LINUX_VERSION_CODE
16248
16249#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16250static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16251 struct net_device *dev,
16252 struct ieee80211_txq_params *params)
16253{
16254 ENTER();
16255 return 0;
16256}
16257#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16258static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16259 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016260{
Jeff Johnsone7245742012-09-05 17:12:55 -070016261 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070016262 return 0;
16263}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016264#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070016265
16266#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16267static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016268 struct net_device *dev,
16269 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016270{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016271 int ret;
16272
16273 vos_ssr_protect(__func__);
16274 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
16275 vos_ssr_unprotect(__func__);
16276 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016277}
16278#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16279static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
16280 struct ieee80211_txq_params *params)
16281{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016282 int ret;
16283
16284 vos_ssr_protect(__func__);
16285 ret = __wlan_hdd_set_txq_params(wiphy, params);
16286 vos_ssr_unprotect(__func__);
16287 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016288}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016289#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016290
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016291static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016292 struct net_device *dev,
16293 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070016294{
16295 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016296 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016297 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016298 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016299 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016300 v_CONTEXT_t pVosContext = NULL;
16301 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016302
Jeff Johnsone7245742012-09-05 17:12:55 -070016303 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016304
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016305 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016306 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016307 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016308 return -EINVAL;
16309 }
16310
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016311 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16312 TRACE_CODE_HDD_CFG80211_DEL_STA,
16313 pAdapter->sessionId, pAdapter->device_mode));
16314
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016315 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16316 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016317 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016318 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016319 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016320 }
16321
Jeff Johnson295189b2012-06-20 16:38:30 -070016322 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016323 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016324 )
16325 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016326 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16327 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16328 if(pSapCtx == NULL){
16329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16330 FL("psapCtx is NULL"));
16331 return -ENOENT;
16332 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016333 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016334 {
16335 v_U16_t i;
16336 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16337 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016338 if ((pSapCtx->aStaInfo[i].isUsed) &&
16339 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016340 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016341 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016342 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016343 ETHER_ADDR_LEN);
16344
Jeff Johnson295189b2012-06-20 16:38:30 -070016345 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016346 "%s: Delete STA with MAC::"
16347 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016348 __func__,
16349 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16350 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016351 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016352 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016353 }
16354 }
16355 }
16356 else
16357 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016358
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016359 vos_status = hdd_softap_GetStaId(pAdapter,
16360 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016361 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16362 {
16363 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016364 "%s: Skip this DEL STA as this is not used::"
16365 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016366 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016367 return -ENOENT;
16368 }
16369
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016370 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016371 {
16372 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016373 "%s: Skip this DEL STA as deauth is in progress::"
16374 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016375 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016376 return -ENOENT;
16377 }
16378
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016379 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016380
Jeff Johnson295189b2012-06-20 16:38:30 -070016381 hddLog(VOS_TRACE_LEVEL_INFO,
16382 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016383 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016384 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016385 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016386
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016387 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016388 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16389 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016390 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016391 hddLog(VOS_TRACE_LEVEL_INFO,
16392 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016393 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016394 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016395 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016396 return -ENOENT;
16397 }
16398
Jeff Johnson295189b2012-06-20 16:38:30 -070016399 }
16400 }
16401
16402 EXIT();
16403
16404 return 0;
16405}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016406
16407#ifdef CFG80211_DEL_STA_V2
16408static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16409 struct net_device *dev,
16410 struct station_del_parameters *param)
16411#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016412#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16413static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16414 struct net_device *dev, const u8 *mac)
16415#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016416static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16417 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016418#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016419#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016420{
16421 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016422 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016423
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016424 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016425
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016426#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016427 if (NULL == param) {
16428 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016429 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016430 return -EINVAL;
16431 }
16432
16433 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16434 param->subtype, &delStaParams);
16435
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016436#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016437 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016438 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016439#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016440 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16441
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016442 vos_ssr_unprotect(__func__);
16443
16444 return ret;
16445}
16446
16447static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016448 struct net_device *dev,
16449#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16450 const u8 *mac,
16451#else
16452 u8 *mac,
16453#endif
16454 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016455{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016456 hdd_adapter_t *pAdapter;
16457 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016458 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016459#ifdef FEATURE_WLAN_TDLS
16460 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016461
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016462 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016463
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016464 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16465 if (NULL == pAdapter)
16466 {
16467 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16468 "%s: Adapter is NULL",__func__);
16469 return -EINVAL;
16470 }
16471 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16472 status = wlan_hdd_validate_context(pHddCtx);
16473 if (0 != status)
16474 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016475 return status;
16476 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016477
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016478 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16479 TRACE_CODE_HDD_CFG80211_ADD_STA,
16480 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016481 mask = params->sta_flags_mask;
16482
16483 set = params->sta_flags_set;
16484
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016485 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016486 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16487 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016488
16489 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16490 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016491 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016492 }
16493 }
16494#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016495 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016496 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016497}
16498
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016499#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16500static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16501 struct net_device *dev, const u8 *mac,
16502 struct station_parameters *params)
16503#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016504static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16505 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016506#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016507{
16508 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016509
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016510 vos_ssr_protect(__func__);
16511 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16512 vos_ssr_unprotect(__func__);
16513
16514 return ret;
16515}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016516#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016517
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016518static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016519 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016520{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016521 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16522 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016523 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016524 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016525 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016526 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016527
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016528 ENTER();
16529
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016530 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016531 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016532 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016533 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016534 return -EINVAL;
16535 }
16536
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016537 if (!pmksa) {
16538 hddLog(LOGE, FL("pmksa is NULL"));
16539 return -EINVAL;
16540 }
16541
16542 if (!pmksa->bssid || !pmksa->pmkid) {
16543 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16544 pmksa->bssid, pmksa->pmkid);
16545 return -EINVAL;
16546 }
16547
16548 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16549 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16550
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016551 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16552 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016553 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016554 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016555 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016556 }
16557
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016558 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016559 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16560
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016561 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16562 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016563
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016564 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016565 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016566 &pmk_id, 1, FALSE);
16567
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016568 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16569 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16570 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016571
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016572 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016573 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016574}
16575
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016576static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16577 struct cfg80211_pmksa *pmksa)
16578{
16579 int ret;
16580
16581 vos_ssr_protect(__func__);
16582 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16583 vos_ssr_unprotect(__func__);
16584
16585 return ret;
16586}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016587
Wilson Yang6507c4e2013-10-01 20:11:19 -070016588
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016589static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016590 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016591{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016592 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16593 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016594 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016595 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016596
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016597 ENTER();
16598
Wilson Yang6507c4e2013-10-01 20:11:19 -070016599 /* Validate pAdapter */
16600 if (NULL == pAdapter)
16601 {
16602 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16603 return -EINVAL;
16604 }
16605
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016606 if (!pmksa) {
16607 hddLog(LOGE, FL("pmksa is NULL"));
16608 return -EINVAL;
16609 }
16610
16611 if (!pmksa->bssid) {
16612 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16613 return -EINVAL;
16614 }
16615
Kiet Lam98c46a12014-10-31 15:34:57 -070016616 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16617 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16618
Wilson Yang6507c4e2013-10-01 20:11:19 -070016619 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16620 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016621 if (0 != status)
16622 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016623 return status;
16624 }
16625
16626 /*Retrieve halHandle*/
16627 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16628
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016629 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16630 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16631 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016632 /* Delete the PMKID CSR cache */
16633 if (eHAL_STATUS_SUCCESS !=
16634 sme_RoamDelPMKIDfromCache(halHandle,
16635 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16636 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16637 MAC_ADDR_ARRAY(pmksa->bssid));
16638 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016639 }
16640
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016641 EXIT();
16642 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016643}
16644
Wilson Yang6507c4e2013-10-01 20:11:19 -070016645
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016646static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16647 struct cfg80211_pmksa *pmksa)
16648{
16649 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016650
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016651 vos_ssr_protect(__func__);
16652 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16653 vos_ssr_unprotect(__func__);
16654
16655 return ret;
16656
16657}
16658
16659static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016660{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016661 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16662 tHalHandle halHandle;
16663 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016664 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016665
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016666 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016667
16668 /* Validate pAdapter */
16669 if (NULL == pAdapter)
16670 {
16671 hddLog(VOS_TRACE_LEVEL_ERROR,
16672 "%s: Invalid Adapter" ,__func__);
16673 return -EINVAL;
16674 }
16675
16676 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16677 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016678 if (0 != status)
16679 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016680 return status;
16681 }
16682
16683 /*Retrieve halHandle*/
16684 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16685
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016686 /* Flush the PMKID cache in CSR */
16687 if (eHAL_STATUS_SUCCESS !=
16688 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
16689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
16690 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016691 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016692 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080016693 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016694}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016695
16696static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
16697{
16698 int ret;
16699
16700 vos_ssr_protect(__func__);
16701 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
16702 vos_ssr_unprotect(__func__);
16703
16704 return ret;
16705}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016706#endif
16707
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016708#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016709static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16710 struct net_device *dev,
16711 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016712{
16713 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16714 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016715 hdd_context_t *pHddCtx;
16716 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016717
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016718 ENTER();
16719
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016720 if (NULL == pAdapter)
16721 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016722 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016723 return -ENODEV;
16724 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016725 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16726 ret = wlan_hdd_validate_context(pHddCtx);
16727 if (0 != ret)
16728 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016729 return ret;
16730 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016731 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016732 if (NULL == pHddStaCtx)
16733 {
16734 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
16735 return -EINVAL;
16736 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016737
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016738 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16739 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
16740 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016741 // Added for debug on reception of Re-assoc Req.
16742 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
16743 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016744 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016745 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080016746 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016747 }
16748
16749#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080016750 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016751 ftie->ie_len);
16752#endif
16753
16754 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016755 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
16756 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016757 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016758
16759 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016760 return 0;
16761}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016762
16763static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16764 struct net_device *dev,
16765 struct cfg80211_update_ft_ies_params *ftie)
16766{
16767 int ret;
16768
16769 vos_ssr_protect(__func__);
16770 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
16771 vos_ssr_unprotect(__func__);
16772
16773 return ret;
16774}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016775#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016776
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016777#ifdef FEATURE_WLAN_SCAN_PNO
16778
16779void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
16780 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
16781{
16782 int ret;
16783 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
16784 hdd_context_t *pHddCtx;
16785
Nirav Shah80830bf2013-12-31 16:35:12 +053016786 ENTER();
16787
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016788 if (NULL == pAdapter)
16789 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016791 "%s: HDD adapter is Null", __func__);
16792 return ;
16793 }
16794
16795 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16796 if (NULL == pHddCtx)
16797 {
16798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16799 "%s: HDD context is Null!!!", __func__);
16800 return ;
16801 }
16802
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016803 spin_lock(&pHddCtx->schedScan_lock);
16804 if (TRUE == pHddCtx->isWiphySuspended)
16805 {
16806 pHddCtx->isSchedScanUpdatePending = TRUE;
16807 spin_unlock(&pHddCtx->schedScan_lock);
16808 hddLog(VOS_TRACE_LEVEL_INFO,
16809 "%s: Update cfg80211 scan database after it resume", __func__);
16810 return ;
16811 }
16812 spin_unlock(&pHddCtx->schedScan_lock);
16813
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016814 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
16815
16816 if (0 > ret)
16817 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053016818 else
16819 {
16820 /* Acquire wakelock to handle the case where APP's tries to suspend
16821 * immediatly after the driver gets connect request(i.e after pno)
16822 * from supplicant, this result in app's is suspending and not able
16823 * to process the connect request to AP */
16824 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
16825 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016826 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16828 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016829}
16830
16831/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016832 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016833 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016834 */
16835static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
16836{
16837 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16838 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016839 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016840 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16841 int status = 0;
16842 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
16843
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016844 /* The current firmware design does not allow PNO during any
16845 * active sessions. Hence, determine the active sessions
16846 * and return a failure.
16847 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016848 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
16849 {
16850 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016851 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016852
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016853 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
16854 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
16855 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
16856 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
16857 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053016858 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016859 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016860 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016861 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016862 }
16863 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16864 pAdapterNode = pNext;
16865 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016866 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016867}
16868
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016869void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
16870{
16871 hdd_adapter_t *pAdapter = callbackContext;
16872 hdd_context_t *pHddCtx;
16873
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016874 ENTER();
16875
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016876 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
16877 {
16878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16879 FL("Invalid adapter or adapter has invalid magic"));
16880 return;
16881 }
16882
16883 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16884 if (0 != wlan_hdd_validate_context(pHddCtx))
16885 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016886 return;
16887 }
16888
c_hpothub53c45d2014-08-18 16:53:14 +053016889 if (VOS_STATUS_SUCCESS != status)
16890 {
16891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016892 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053016893 pHddCtx->isPnoEnable = FALSE;
16894 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016895
16896 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
16897 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016898 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016899}
16900
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016901/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016902 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
16903 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016904 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016905static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016906 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16907{
16908 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016909 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016910 hdd_context_t *pHddCtx;
16911 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016912 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053016913 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
16914 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016915 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16916 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016917 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016918 hdd_config_t *pConfig = NULL;
16919 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016920
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016921 ENTER();
16922
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016923 if (NULL == pAdapter)
16924 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016926 "%s: HDD adapter is Null", __func__);
16927 return -ENODEV;
16928 }
16929
16930 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016931 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016932
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016933 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016934 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016935 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016936 }
16937
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016938 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016939 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16940 if (NULL == hHal)
16941 {
16942 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16943 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016944 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016945 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016946 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16947 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
16948 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053016949 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016950 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053016951 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016952 {
16953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16954 "%s: aborting the existing scan is unsuccessfull", __func__);
16955 return -EBUSY;
16956 }
16957
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016958 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016959 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016961 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016962 return -EBUSY;
16963 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016964
c_hpothu37f21312014-04-09 21:49:54 +053016965 if (TRUE == pHddCtx->isPnoEnable)
16966 {
16967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16968 FL("already PNO is enabled"));
16969 return -EBUSY;
16970 }
c_hpothu225aa7c2014-10-22 17:45:13 +053016971
16972 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
16973 {
16974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16975 "%s: abort ROC failed ", __func__);
16976 return -EBUSY;
16977 }
16978
c_hpothu37f21312014-04-09 21:49:54 +053016979 pHddCtx->isPnoEnable = TRUE;
16980
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016981 pnoRequest.enable = 1; /*Enable PNO */
16982 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016983
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016984 if (( !pnoRequest.ucNetworksCount ) ||
16985 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016986 {
16987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016988 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016989 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016990 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016991 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016992 goto error;
16993 }
16994
16995 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
16996 {
16997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016998 "%s: Incorrect number of channels %d",
16999 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017000 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017001 goto error;
17002 }
17003
17004 /* Framework provides one set of channels(all)
17005 * common for all saved profile */
17006 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17007 channels_allowed, &num_channels_allowed))
17008 {
17009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17010 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017011 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017012 goto error;
17013 }
17014 /* Checking each channel against allowed channel list */
17015 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053017016 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017017 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017018 char chList [(request->n_channels*5)+1];
17019 int len;
17020 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017021 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017022 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017023 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017024 if (request->channels[i]->hw_value == channels_allowed[indx])
17025 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017026 if ((!pConfig->enableDFSPnoChnlScan) &&
17027 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
17028 {
17029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17030 "%s : Dropping DFS channel : %d",
17031 __func__,channels_allowed[indx]);
17032 num_ignore_dfs_ch++;
17033 break;
17034 }
17035
Nirav Shah80830bf2013-12-31 16:35:12 +053017036 valid_ch[num_ch++] = request->channels[i]->hw_value;
17037 len += snprintf(chList+len, 5, "%d ",
17038 request->channels[i]->hw_value);
17039 break ;
17040 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017041 }
17042 }
Nirav Shah80830bf2013-12-31 16:35:12 +053017043 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017044
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017045 /*If all channels are DFS and dropped, then ignore the PNO request*/
17046 if (num_ignore_dfs_ch == request->n_channels)
17047 {
17048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17049 "%s : All requested channels are DFS channels", __func__);
17050 ret = -EINVAL;
17051 goto error;
17052 }
17053 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017054
17055 pnoRequest.aNetworks =
17056 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17057 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017058 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017059 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17060 FL("failed to allocate memory aNetworks %u"),
17061 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17062 goto error;
17063 }
17064 vos_mem_zero(pnoRequest.aNetworks,
17065 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17066
17067 /* Filling per profile params */
17068 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
17069 {
17070 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017071 request->match_sets[i].ssid.ssid_len;
17072
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017073 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
17074 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017075 {
17076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017077 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017078 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017079 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017080 goto error;
17081 }
17082
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017083 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017084 request->match_sets[i].ssid.ssid,
17085 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017086 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17087 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017088 i, pnoRequest.aNetworks[i].ssId.ssId);
17089 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
17090 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
17091 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017092
17093 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017094 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
17095 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017096
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017097 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017098 }
17099
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017100 for (i = 0; i < request->n_ssids; i++)
17101 {
17102 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017103 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017104 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017105 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017106 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017107 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017108 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017109 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017110 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017111 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017112 break;
17113 }
17114 j++;
17115 }
17116 }
17117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17118 "Number of hidden networks being Configured = %d",
17119 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080017121 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017122
17123 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17124 if (pnoRequest.p24GProbeTemplate == NULL)
17125 {
17126 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17127 FL("failed to allocate memory p24GProbeTemplate %u"),
17128 SIR_PNO_MAX_PB_REQ_SIZE);
17129 goto error;
17130 }
17131
17132 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17133 if (pnoRequest.p5GProbeTemplate == NULL)
17134 {
17135 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17136 FL("failed to allocate memory p5GProbeTemplate %u"),
17137 SIR_PNO_MAX_PB_REQ_SIZE);
17138 goto error;
17139 }
17140
17141 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17142 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17143
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053017144 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
17145 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017146 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017147 pnoRequest.us24GProbeTemplateLen = request->ie_len;
17148 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
17149 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017150
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017151 pnoRequest.us5GProbeTemplateLen = request->ie_len;
17152 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
17153 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017154 }
17155
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017156 /* Driver gets only one time interval which is hardcoded in
17157 * supplicant for 10000ms. Taking power consumption into account 6 timers
17158 * will be used, Timervalue is increased exponentially i.e 10,20,40,
17159 * 80,160,320 secs. And number of scan cycle for each timer
17160 * is configurable through INI param gPNOScanTimerRepeatValue.
17161 * If it is set to 0 only one timer will be used and PNO scan cycle
17162 * will be repeated after each interval specified by supplicant
17163 * till PNO is disabled.
17164 */
17165 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017166 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017167 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017168 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017169 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
17170
17171 tempInterval = (request->interval)/1000;
17172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17173 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
17174 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017175 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017176 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017177 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017178 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017179 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017180 tempInterval *= 2;
17181 }
17182 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017183 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017184
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017185 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017186
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017187 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017188 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17189 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017190 pAdapter->pno_req_status = 0;
17191
Nirav Shah80830bf2013-12-31 16:35:12 +053017192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17193 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017194 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
17195 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053017196
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017197 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017198 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017199 hdd_cfg80211_sched_scan_done_callback, pAdapter);
17200 if (eHAL_STATUS_SUCCESS != status)
17201 {
17202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017203 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017204 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017205 goto error;
17206 }
17207
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017208 ret = wait_for_completion_timeout(
17209 &pAdapter->pno_comp_var,
17210 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17211 if (0 >= ret)
17212 {
17213 // Did not receive the response for PNO enable in time.
17214 // Assuming the PNO enable was success.
17215 // Returning error from here, because we timeout, results
17216 // in side effect of Wifi (Wifi Setting) not to work.
17217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17218 FL("Timed out waiting for PNO to be Enabled"));
17219 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017220 }
17221
17222 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053017223 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017224
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017225error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17227 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053017228 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017229 if (pnoRequest.aNetworks)
17230 vos_mem_free(pnoRequest.aNetworks);
17231 if (pnoRequest.p24GProbeTemplate)
17232 vos_mem_free(pnoRequest.p24GProbeTemplate);
17233 if (pnoRequest.p5GProbeTemplate)
17234 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017235
17236 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017237 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017238}
17239
17240/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017241 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
17242 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017243 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017244static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
17245 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17246{
17247 int ret;
17248
17249 vos_ssr_protect(__func__);
17250 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
17251 vos_ssr_unprotect(__func__);
17252
17253 return ret;
17254}
17255
17256/*
17257 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
17258 * Function to disable PNO
17259 */
17260static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017261 struct net_device *dev)
17262{
17263 eHalStatus status = eHAL_STATUS_FAILURE;
17264 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17265 hdd_context_t *pHddCtx;
17266 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017267 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017268 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017269
17270 ENTER();
17271
17272 if (NULL == pAdapter)
17273 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017275 "%s: HDD adapter is Null", __func__);
17276 return -ENODEV;
17277 }
17278
17279 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017280
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017281 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017282 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017284 "%s: HDD context is Null", __func__);
17285 return -ENODEV;
17286 }
17287
17288 /* The return 0 is intentional when isLogpInProgress and
17289 * isLoadUnloadInProgress. We did observe a crash due to a return of
17290 * failure in sched_scan_stop , especially for a case where the unload
17291 * of the happens at the same time. The function __cfg80211_stop_sched_scan
17292 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
17293 * success. If it returns a failure , then its next invocation due to the
17294 * clean up of the second interface will have the dev pointer corresponding
17295 * to the first one leading to a crash.
17296 */
17297 if (pHddCtx->isLogpInProgress)
17298 {
17299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17300 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017301 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017302 return ret;
17303 }
17304
Mihir Shete18156292014-03-11 15:38:30 +053017305 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017306 {
17307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17308 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17309 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017310 }
17311
17312 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17313 if (NULL == hHal)
17314 {
17315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17316 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017317 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017318 }
17319
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017320 pnoRequest.enable = 0; /* Disable PNO */
17321 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017322
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017323 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17324 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17325 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017326
17327 INIT_COMPLETION(pAdapter->pno_comp_var);
17328 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17329 pnoRequest.callbackContext = pAdapter;
17330 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017331 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017332 pAdapter->sessionId,
17333 NULL, pAdapter);
17334 if (eHAL_STATUS_SUCCESS != status)
17335 {
17336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17337 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017338 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017339 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017340 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017341 ret = wait_for_completion_timeout(
17342 &pAdapter->pno_comp_var,
17343 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17344 if (0 >= ret)
17345 {
17346 // Did not receive the response for PNO disable in time.
17347 // Assuming the PNO disable was success.
17348 // Returning error from here, because we timeout, results
17349 // in side effect of Wifi (Wifi Setting) not to work.
17350 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17351 FL("Timed out waiting for PNO to be disabled"));
17352 ret = 0;
17353 }
17354
17355 ret = pAdapter->pno_req_status;
17356 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017357
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017358error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017360 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017361
17362 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017363 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017364}
17365
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017366/*
17367 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17368 * NL interface to disable PNO
17369 */
17370static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17371 struct net_device *dev)
17372{
17373 int ret;
17374
17375 vos_ssr_protect(__func__);
17376 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17377 vos_ssr_unprotect(__func__);
17378
17379 return ret;
17380}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017381#endif /*FEATURE_WLAN_SCAN_PNO*/
17382
17383
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017384#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017385#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017386static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17387 struct net_device *dev,
17388 u8 *peer, u8 action_code,
17389 u8 dialog_token,
17390 u16 status_code, u32 peer_capability,
17391 const u8 *buf, size_t len)
17392#else /* TDLS_MGMT_VERSION2 */
17393#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17394static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17395 struct net_device *dev,
17396 const u8 *peer, u8 action_code,
17397 u8 dialog_token, u16 status_code,
17398 u32 peer_capability, bool initiator,
17399 const u8 *buf, size_t len)
17400#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17401static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17402 struct net_device *dev,
17403 const u8 *peer, u8 action_code,
17404 u8 dialog_token, u16 status_code,
17405 u32 peer_capability, const u8 *buf,
17406 size_t len)
17407#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17408static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17409 struct net_device *dev,
17410 u8 *peer, u8 action_code,
17411 u8 dialog_token,
17412 u16 status_code, u32 peer_capability,
17413 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017414#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017415static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17416 struct net_device *dev,
17417 u8 *peer, u8 action_code,
17418 u8 dialog_token,
17419 u16 status_code, const u8 *buf,
17420 size_t len)
17421#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017422#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017423{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017424 hdd_adapter_t *pAdapter;
17425 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017426 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017427 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017428 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017429 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017430 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017431 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017432#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017433 u32 peer_capability = 0;
17434#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017435 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017436 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017437
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017438 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17439 if (NULL == pAdapter)
17440 {
17441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17442 "%s: Adapter is NULL",__func__);
17443 return -EINVAL;
17444 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017445 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17446 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17447 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017448
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017449 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017450 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017451 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017452 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017453 "Invalid arguments");
17454 return -EINVAL;
17455 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017456
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017457 if (pHddCtx->isLogpInProgress)
17458 {
17459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17460 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017461 wlan_hdd_tdls_set_link_status(pAdapter,
17462 peer,
17463 eTDLS_LINK_IDLE,
17464 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017465 return -EBUSY;
17466 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017467
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017468 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17469 {
17470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17471 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17472 return -EAGAIN;
17473 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017474
Hoonki Lee27511902013-03-14 18:19:06 -070017475 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017476 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017478 "%s: TDLS mode is disabled OR not enabled in FW."
17479 MAC_ADDRESS_STR " action %d declined.",
17480 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017481 return -ENOTSUPP;
17482 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017483
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017484 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17485
17486 if( NULL == pHddStaCtx )
17487 {
17488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17489 "%s: HDD station context NULL ",__func__);
17490 return -EINVAL;
17491 }
17492
17493 /* STA should be connected and authenticated
17494 * before sending any TDLS frames
17495 */
17496 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17497 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17498 {
17499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17500 "STA is not connected or unauthenticated. "
17501 "connState %u, uIsAuthenticated %u",
17502 pHddStaCtx->conn_info.connState,
17503 pHddStaCtx->conn_info.uIsAuthenticated);
17504 return -EAGAIN;
17505 }
17506
Hoonki Lee27511902013-03-14 18:19:06 -070017507 /* other than teardown frame, other mgmt frames are not sent if disabled */
17508 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17509 {
17510 /* if tdls_mode is disabled to respond to peer's request */
17511 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17512 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017514 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017515 " TDLS mode is disabled. action %d declined.",
17516 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017517
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017518 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017519 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017520
17521 if (vos_max_concurrent_connections_reached())
17522 {
17523 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17524 return -EINVAL;
17525 }
Hoonki Lee27511902013-03-14 18:19:06 -070017526 }
17527
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017528 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17529 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017530 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017531 {
17532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017533 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017534 " TDLS setup is ongoing. action %d declined.",
17535 __func__, MAC_ADDR_ARRAY(peer), action_code);
17536 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017537 }
17538 }
17539
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017540 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17541 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017542 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017543 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17544 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017545 {
17546 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17547 we return error code at 'add_station()'. Hence we have this
17548 check again in addtion to add_station().
17549 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017550 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017551 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17553 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017554 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
17555 __func__, MAC_ADDR_ARRAY(peer), action_code,
17556 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053017557 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080017558 }
17559 else
17560 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017561 /* maximum reached. tweak to send error code to peer and return
17562 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017563 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17565 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017566 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
17567 __func__, MAC_ADDR_ARRAY(peer), status_code,
17568 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070017569 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017570 /* fall through to send setup resp with failure status
17571 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017572 }
17573 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017574 else
17575 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017576 mutex_lock(&pHddCtx->tdls_lock);
17577 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017578 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017579 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017580 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017582 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17583 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017584 return -EPERM;
17585 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017586 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017587 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017588 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017589
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017591 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017592 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17593 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017594
Hoonki Leea34dd892013-02-05 22:56:02 -080017595 /*Except teardown responder will not be used so just make 0*/
17596 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017597 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017598 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017599
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017600 mutex_lock(&pHddCtx->tdls_lock);
17601 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017602
17603 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17604 responder = pTdlsPeer->is_responder;
17605 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017606 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017608 "%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 -070017609 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17610 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017611 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017612 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017613 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017614 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017615 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017616
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017617 /* Discard TDLS setup if peer is removed by user app */
17618 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
17619 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17620 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
17621 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
17622
17623 mutex_lock(&pHddCtx->tdls_lock);
17624 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17625 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
17626 mutex_unlock(&pHddCtx->tdls_lock);
17627 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
17628 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
17629 MAC_ADDR_ARRAY(peer), action_code);
17630 return -EINVAL;
17631 }
17632 mutex_unlock(&pHddCtx->tdls_lock);
17633 }
17634
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017635 /* For explicit trigger of DIS_REQ come out of BMPS for
17636 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017637 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053017638 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017639 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17640 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070017641 {
17642 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
17643 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017645 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017646 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
17647 if (status != VOS_STATUS_SUCCESS) {
17648 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
17649 }
Hoonki Lee14621352013-04-16 17:51:19 -070017650 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017651 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017652 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
17654 }
17655 }
Hoonki Lee14621352013-04-16 17:51:19 -070017656 }
17657
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017658 /* make sure doesn't call send_mgmt() while it is pending */
17659 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
17660 {
17661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017662 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017663 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017664 ret = -EBUSY;
17665 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017666 }
17667
17668 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017669 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
17670
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017671 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
17672 pAdapter->sessionId, peer, action_code, dialog_token,
17673 status_code, peer_capability, (tANI_U8 *)buf, len,
17674 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017675
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017676 if (VOS_STATUS_SUCCESS != status)
17677 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17679 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017680 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017681 ret = -EINVAL;
17682 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017683 }
17684
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17686 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
17687 WAIT_TIME_TDLS_MGMT);
17688
Hoonki Leed37cbb32013-04-20 00:31:14 -070017689 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
17690 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
17691
17692 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017693 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070017694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070017695 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070017696 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017697 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080017698
17699 if (pHddCtx->isLogpInProgress)
17700 {
17701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17702 "%s: LOGP in Progress. Ignore!!!", __func__);
17703 return -EAGAIN;
17704 }
Abhishek Singh837adf22015-10-01 17:37:37 +053017705 if (rc <= 0)
17706 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
17707 WLAN_LOG_INDICATOR_HOST_DRIVER,
17708 WLAN_LOG_REASON_HDD_TIME_OUT,
17709 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080017710
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017711 ret = -EINVAL;
17712 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017713 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017714 else
17715 {
17716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17717 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
17718 __func__, rc, pAdapter->mgmtTxCompletionStatus);
17719 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017720
Gopichand Nakkala05922802013-03-14 12:23:19 -070017721 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070017722 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017723 ret = max_sta_failed;
17724 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070017725 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017726
Hoonki Leea34dd892013-02-05 22:56:02 -080017727 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
17728 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017729 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17731 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017732 }
17733 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
17734 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017735 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017736 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17737 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017738 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017739
17740 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017741
17742tx_failed:
17743 /* add_station will be called before sending TDLS_SETUP_REQ and
17744 * TDLS_SETUP_RSP and as part of add_station driver will enable
17745 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
17746 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
17747 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
17748 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
17749 */
17750
17751 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17752 (SIR_MAC_TDLS_SETUP_RSP == action_code))
17753 wlan_hdd_tdls_check_bmps(pAdapter);
17754 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017755}
17756
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017757#if TDLS_MGMT_VERSION2
17758static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17759 u8 *peer, u8 action_code, u8 dialog_token,
17760 u16 status_code, u32 peer_capability,
17761 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017762#else /* TDLS_MGMT_VERSION2 */
17763#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17764static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17765 struct net_device *dev,
17766 const u8 *peer, u8 action_code,
17767 u8 dialog_token, u16 status_code,
17768 u32 peer_capability, bool initiator,
17769 const u8 *buf, size_t len)
17770#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17771static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17772 struct net_device *dev,
17773 const u8 *peer, u8 action_code,
17774 u8 dialog_token, u16 status_code,
17775 u32 peer_capability, const u8 *buf,
17776 size_t len)
17777#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17778static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17779 struct net_device *dev,
17780 u8 *peer, u8 action_code,
17781 u8 dialog_token,
17782 u16 status_code, u32 peer_capability,
17783 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017784#else
17785static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17786 u8 *peer, u8 action_code, u8 dialog_token,
17787 u16 status_code, const u8 *buf, size_t len)
17788#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017789#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017790{
17791 int ret;
17792
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017793 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017794#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017795 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17796 dialog_token, status_code,
17797 peer_capability, buf, len);
17798#else /* TDLS_MGMT_VERSION2 */
17799#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17800 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17801 dialog_token, status_code,
17802 peer_capability, initiator,
17803 buf, len);
17804#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17805 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17806 dialog_token, status_code,
17807 peer_capability, buf, len);
17808#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17809 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17810 dialog_token, status_code,
17811 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017812#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017813 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17814 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017815#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017816#endif
17817 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017818
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017819 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017820}
Atul Mittal115287b2014-07-08 13:26:33 +053017821
17822int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017823#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17824 const u8 *peer,
17825#else
Atul Mittal115287b2014-07-08 13:26:33 +053017826 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017827#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017828 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053017829 cfg80211_exttdls_callback callback)
17830{
17831
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017832 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053017833 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017834 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053017835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17836 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
17837 __func__, MAC_ADDR_ARRAY(peer));
17838
17839 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17840 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17841
17842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017843 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17844 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17845 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017846 return -ENOTSUPP;
17847 }
17848
17849 /* To cater the requirement of establishing the TDLS link
17850 * irrespective of the data traffic , get an entry of TDLS peer.
17851 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017852 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017853 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
17854 if (pTdlsPeer == NULL) {
17855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17856 "%s: peer " MAC_ADDRESS_STR " not existing",
17857 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017858 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017859 return -EINVAL;
17860 }
17861
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017862 /* check FW TDLS Off Channel capability */
17863 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017864 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017865 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017866 {
17867 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
17868 pTdlsPeer->peerParams.global_operating_class =
17869 tdls_peer_params->global_operating_class;
17870 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
17871 pTdlsPeer->peerParams.min_bandwidth_kbps =
17872 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017873 /* check configured channel is valid, non dfs and
17874 * not current operating channel */
17875 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
17876 tdls_peer_params->channel)) &&
17877 (pHddStaCtx) &&
17878 (tdls_peer_params->channel !=
17879 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017880 {
17881 pTdlsPeer->isOffChannelConfigured = TRUE;
17882 }
17883 else
17884 {
17885 pTdlsPeer->isOffChannelConfigured = FALSE;
17886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17887 "%s: Configured Tdls Off Channel is not valid", __func__);
17888
17889 }
17890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017891 "%s: tdls_off_channel %d isOffChannelConfigured %d "
17892 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017893 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017894 pTdlsPeer->isOffChannelConfigured,
17895 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017896 }
17897 else
17898 {
17899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017900 "%s: TDLS off channel FW capability %d, "
17901 "host capab %d or Invalid TDLS Peer Params", __func__,
17902 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
17903 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017904 }
17905
Atul Mittal115287b2014-07-08 13:26:33 +053017906 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
17907
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017908 mutex_unlock(&pHddCtx->tdls_lock);
17909
Atul Mittal115287b2014-07-08 13:26:33 +053017910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17911 " %s TDLS Add Force Peer Failed",
17912 __func__);
17913 return -EINVAL;
17914 }
17915 /*EXT TDLS*/
17916
17917 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017918 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17920 " %s TDLS set callback Failed",
17921 __func__);
17922 return -EINVAL;
17923 }
17924
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017925 mutex_unlock(&pHddCtx->tdls_lock);
17926
Atul Mittal115287b2014-07-08 13:26:33 +053017927 return(0);
17928
17929}
17930
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017931int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
17932#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17933 const u8 *peer
17934#else
17935 u8 *peer
17936#endif
17937)
Atul Mittal115287b2014-07-08 13:26:33 +053017938{
17939
17940 hddTdlsPeer_t *pTdlsPeer;
17941 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053017942
Atul Mittal115287b2014-07-08 13:26:33 +053017943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17944 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
17945 __func__, MAC_ADDR_ARRAY(peer));
17946
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017947 if (0 != wlan_hdd_validate_context(pHddCtx)) {
17948 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
17949 return -EINVAL;
17950 }
17951
Atul Mittal115287b2014-07-08 13:26:33 +053017952 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17953 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17954
17955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017956 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17957 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17958 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017959 return -ENOTSUPP;
17960 }
17961
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017962 mutex_lock(&pHddCtx->tdls_lock);
17963 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053017964
17965 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017966 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017967 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017968 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053017969 __func__, MAC_ADDR_ARRAY(peer));
17970 return -EINVAL;
17971 }
17972 else {
17973 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
17974 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053017975 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
17976 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017977 /* if channel switch is configured, reset
17978 the channel for this peer */
17979 if (TRUE == pTdlsPeer->isOffChannelConfigured)
17980 {
17981 pTdlsPeer->peerParams.channel = 0;
17982 pTdlsPeer->isOffChannelConfigured = FALSE;
17983 }
Atul Mittal115287b2014-07-08 13:26:33 +053017984 }
17985
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017986 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017987 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017988 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053017989 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017990 }
Atul Mittal115287b2014-07-08 13:26:33 +053017991
17992 /*EXT TDLS*/
17993
17994 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017995 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17997 " %s TDLS set callback Failed",
17998 __func__);
17999 return -EINVAL;
18000 }
Atul Mittal115287b2014-07-08 13:26:33 +053018001
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018002 mutex_unlock(&pHddCtx->tdls_lock);
18003
18004 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053018005}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018006static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018007#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18008 const u8 *peer,
18009#else
18010 u8 *peer,
18011#endif
18012 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018013{
18014 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18015 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018016 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018017 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018018
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018019 ENTER();
18020
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018021 if (!pAdapter) {
18022 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
18023 return -EINVAL;
18024 }
18025
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018026 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18027 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
18028 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018029 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018030 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070018032 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018033 return -EINVAL;
18034 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018035
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018036 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018037 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018038 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018039 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018040 }
18041
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018042
18043 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018044 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018045 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018046 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018047 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
18048 "Cannot process TDLS commands",
18049 pHddCtx->cfg_ini->fEnableTDLSSupport,
18050 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018051 return -ENOTSUPP;
18052 }
18053
18054 switch (oper) {
18055 case NL80211_TDLS_ENABLE_LINK:
18056 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018057 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018058 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053018059 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
18060 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053018061 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018062 tANI_U16 numCurrTdlsPeers = 0;
18063 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018064 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018065 tSirMacAddr peerMac;
18066 int channel;
18067 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018068
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18070 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
18071 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018072
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018073 mutex_lock(&pHddCtx->tdls_lock);
18074 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018075 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053018076 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018077 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18079 " (oper %d) not exsting. ignored",
18080 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18081 return -EINVAL;
18082 }
18083
18084 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18085 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18086 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18087 "NL80211_TDLS_ENABLE_LINK");
18088
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018089 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
18090 {
18091 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
18092 MAC_ADDRESS_STR " failed",
18093 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018094 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018095 return -EINVAL;
18096 }
18097
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018098 /* before starting tdls connection, set tdls
18099 * off channel established status to default value */
18100 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018101
18102 mutex_unlock(&pHddCtx->tdls_lock);
18103
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053018104 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018105 /* TDLS Off Channel, Disable tdls channel switch,
18106 when there are more than one tdls link */
18107 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053018108 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018109 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018110 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018111 /* get connected peer and send disable tdls off chan */
18112 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018113 if ((connPeer) &&
18114 (connPeer->isOffChannelSupported == TRUE) &&
18115 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018116 {
18117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18118 "%s: More then one peer connected, Disable "
18119 "TDLS channel switch", __func__);
18120
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018121 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018122 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
18123 channel = connPeer->peerParams.channel;
18124
18125 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018126
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018127 ret = sme_SendTdlsChanSwitchReq(
18128 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018129 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018130 peerMac,
18131 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018132 TDLS_OFF_CHANNEL_BW_OFFSET,
18133 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018134 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018135 hddLog(VOS_TRACE_LEVEL_ERROR,
18136 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018137 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018138 }
18139 else
18140 {
18141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18142 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018143 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018144 "isOffChannelConfigured %d",
18145 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018146 (connPeer ? (connPeer->isOffChannelSupported)
18147 : -1),
18148 (connPeer ? (connPeer->isOffChannelConfigured)
18149 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018150 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018151 }
18152 }
18153
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018154 mutex_lock(&pHddCtx->tdls_lock);
18155 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18156 if ( NULL == pTdlsPeer ) {
18157 mutex_unlock(&pHddCtx->tdls_lock);
18158 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18159 "%s: " MAC_ADDRESS_STR
18160 " (oper %d) peer got freed in other context. ignored",
18161 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18162 return -EINVAL;
18163 }
18164 peer_status = pTdlsPeer->link_status;
18165 mutex_unlock(&pHddCtx->tdls_lock);
18166
18167 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018168 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018169 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053018170
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018171 if (0 != wlan_hdd_tdls_get_link_establish_params(
18172 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018173 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018174 return -EINVAL;
18175 }
18176 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018177
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018178 ret = sme_SendTdlsLinkEstablishParams(
18179 WLAN_HDD_GET_HAL_CTX(pAdapter),
18180 pAdapter->sessionId, peer,
18181 &tdlsLinkEstablishParams);
18182 if (ret != VOS_STATUS_SUCCESS) {
18183 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
18184 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018185 /* Send TDLS peer UAPSD capabilities to the firmware and
18186 * register with the TL on after the response for this operation
18187 * is received .
18188 */
18189 ret = wait_for_completion_interruptible_timeout(
18190 &pAdapter->tdls_link_establish_req_comp,
18191 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053018192
18193 mutex_lock(&pHddCtx->tdls_lock);
18194 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18195 if ( NULL == pTdlsPeer ) {
18196 mutex_unlock(&pHddCtx->tdls_lock);
18197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18198 "%s %d: " MAC_ADDRESS_STR
18199 " (oper %d) peer got freed in other context. ignored",
18200 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
18201 (int)oper);
18202 return -EINVAL;
18203 }
18204 peer_status = pTdlsPeer->link_status;
18205 mutex_unlock(&pHddCtx->tdls_lock);
18206
18207 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018208 {
18209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018210 FL("Link Establish Request Failed Status %ld"),
18211 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018212 return -EINVAL;
18213 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018214 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018215
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018216 mutex_lock(&pHddCtx->tdls_lock);
18217 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18218 if ( NULL == pTdlsPeer ) {
18219 mutex_unlock(&pHddCtx->tdls_lock);
18220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18221 "%s: " MAC_ADDRESS_STR
18222 " (oper %d) peer got freed in other context. ignored",
18223 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18224 return -EINVAL;
18225 }
18226
Atul Mittal115287b2014-07-08 13:26:33 +053018227 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18228 eTDLS_LINK_CONNECTED,
18229 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018230 staDesc.ucSTAId = pTdlsPeer->staId;
18231 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053018232
18233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18234 "%s: tdlsLinkEstablishParams of peer "
18235 MAC_ADDRESS_STR "uapsdQueues: %d"
18236 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
18237 "isResponder: %d peerstaId: %d",
18238 __func__,
18239 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
18240 tdlsLinkEstablishParams.uapsdQueues,
18241 tdlsLinkEstablishParams.qos,
18242 tdlsLinkEstablishParams.maxSp,
18243 tdlsLinkEstablishParams.isBufSta,
18244 tdlsLinkEstablishParams.isOffChannelSupported,
18245 tdlsLinkEstablishParams.isResponder,
18246 pTdlsPeer->staId);
18247
18248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18249 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
18250 __func__,
18251 staDesc.ucSTAId,
18252 staDesc.ucQosEnabled);
18253
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018254 ret = WLANTL_UpdateTdlsSTAClient(
18255 pHddCtx->pvosContext,
18256 &staDesc);
18257 if (ret != VOS_STATUS_SUCCESS) {
18258 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
18259 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053018260
Gopichand Nakkala471708b2013-06-04 20:03:01 +053018261 /* Mark TDLS client Authenticated .*/
18262 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
18263 pTdlsPeer->staId,
18264 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018265 if (VOS_STATUS_SUCCESS == status)
18266 {
Hoonki Lee14621352013-04-16 17:51:19 -070018267 if (pTdlsPeer->is_responder == 0)
18268 {
18269 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018270 tdlsConnInfo_t *tdlsInfo;
18271
18272 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
18273
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018274 if (!vos_timer_is_initialized(
18275 &pTdlsPeer->initiatorWaitTimeoutTimer))
18276 {
18277 /* Initialize initiator wait callback */
18278 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018279 &pTdlsPeer->initiatorWaitTimeoutTimer,
18280 VOS_TIMER_TYPE_SW,
18281 wlan_hdd_tdls_initiator_wait_cb,
18282 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018283 }
Hoonki Lee14621352013-04-16 17:51:19 -070018284 wlan_hdd_tdls_timer_restart(pAdapter,
18285 &pTdlsPeer->initiatorWaitTimeoutTimer,
18286 WAIT_TIME_TDLS_INITIATOR);
18287 /* suspend initiator TX until it receives direct packet from the
18288 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018289 ret = WLANTL_SuspendDataTx(
18290 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18291 &staId, NULL);
18292 if (ret != VOS_STATUS_SUCCESS) {
18293 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
18294 }
Hoonki Lee14621352013-04-16 17:51:19 -070018295 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018296
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018297 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018298 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018299 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018300 suppChannelLen =
18301 tdlsLinkEstablishParams.supportedChannelsLen;
18302
18303 if ((suppChannelLen > 0) &&
18304 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
18305 {
18306 tANI_U8 suppPeerChannel = 0;
18307 int i = 0;
18308 for (i = 0U; i < suppChannelLen; i++)
18309 {
18310 suppPeerChannel =
18311 tdlsLinkEstablishParams.supportedChannels[i];
18312
18313 pTdlsPeer->isOffChannelSupported = FALSE;
18314 if (suppPeerChannel ==
18315 pTdlsPeer->peerParams.channel)
18316 {
18317 pTdlsPeer->isOffChannelSupported = TRUE;
18318 break;
18319 }
18320 }
18321 }
18322 else
18323 {
18324 pTdlsPeer->isOffChannelSupported = FALSE;
18325 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018326 }
18327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18328 "%s: TDLS channel switch request for channel "
18329 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018330 "%d isOffChannelSupported %d", __func__,
18331 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018332 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018333 suppChannelLen,
18334 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018335
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018336 /* TDLS Off Channel, Enable tdls channel switch,
18337 when their is only one tdls link and it supports */
18338 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18339 if ((numCurrTdlsPeers == 1) &&
18340 (TRUE == pTdlsPeer->isOffChannelSupported) &&
18341 (TRUE == pTdlsPeer->isOffChannelConfigured))
18342 {
18343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18344 "%s: Send TDLS channel switch request for channel %d",
18345 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018346
18347 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018348 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
18349 channel = pTdlsPeer->peerParams.channel;
18350
18351 mutex_unlock(&pHddCtx->tdls_lock);
18352
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018353 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
18354 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018355 peerMac,
18356 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018357 TDLS_OFF_CHANNEL_BW_OFFSET,
18358 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018359 if (ret != VOS_STATUS_SUCCESS) {
18360 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
18361 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018362 }
18363 else
18364 {
18365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18366 "%s: TDLS channel switch request not sent"
18367 " numCurrTdlsPeers %d "
18368 "isOffChannelSupported %d "
18369 "isOffChannelConfigured %d",
18370 __func__, numCurrTdlsPeers,
18371 pTdlsPeer->isOffChannelSupported,
18372 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018373 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018374 }
18375
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018376 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018377 else
18378 mutex_unlock(&pHddCtx->tdls_lock);
18379
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018380 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018381
18382 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018383 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18384 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018385 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018386 int ac;
18387 uint8 ucAc[4] = { WLANTL_AC_VO,
18388 WLANTL_AC_VI,
18389 WLANTL_AC_BK,
18390 WLANTL_AC_BE };
18391 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18392 for(ac=0; ac < 4; ac++)
18393 {
18394 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18395 pTdlsPeer->staId, ucAc[ac],
18396 tlTid[ac], tlTid[ac], 0, 0,
18397 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018398 if (status != VOS_STATUS_SUCCESS) {
18399 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18400 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018401 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018402 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018403 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018404
Bhargav Shah66896792015-10-01 18:17:37 +053018405 /* stop TCP delack timer if TDLS is enable */
18406 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18407 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053018408 hdd_wlan_tdls_enable_link_event(peer,
18409 pTdlsPeer->isOffChannelSupported,
18410 pTdlsPeer->isOffChannelConfigured,
18411 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018412 }
18413 break;
18414 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018415 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018416 tANI_U16 numCurrTdlsPeers = 0;
18417 hddTdlsPeer_t *connPeer = NULL;
18418
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18420 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18421 __func__, MAC_ADDR_ARRAY(peer));
18422
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018423 mutex_lock(&pHddCtx->tdls_lock);
18424 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018425
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018426
Sunil Dutt41de4e22013-11-14 18:09:02 +053018427 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018428 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018429 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18430 " (oper %d) not exsting. ignored",
18431 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18432 return -EINVAL;
18433 }
18434
18435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18436 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18437 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18438 "NL80211_TDLS_DISABLE_LINK");
18439
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018440 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018441 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018442 long status;
18443
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018444 /* set tdls off channel status to false for this peer */
18445 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018446 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18447 eTDLS_LINK_TEARING,
18448 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18449 eTDLS_LINK_UNSPECIFIED:
18450 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018451 mutex_unlock(&pHddCtx->tdls_lock);
18452
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018453 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18454
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018455 status = sme_DeleteTdlsPeerSta(
18456 WLAN_HDD_GET_HAL_CTX(pAdapter),
18457 pAdapter->sessionId, peer );
18458 if (status != VOS_STATUS_SUCCESS) {
18459 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18460 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018461
18462 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18463 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018464
18465 mutex_lock(&pHddCtx->tdls_lock);
18466 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18467 if ( NULL == pTdlsPeer ) {
18468 mutex_unlock(&pHddCtx->tdls_lock);
18469 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18470 " peer was freed in other context",
18471 __func__, MAC_ADDR_ARRAY(peer));
18472 return -EINVAL;
18473 }
18474
Atul Mittal271a7652014-09-12 13:18:22 +053018475 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053018476 eTDLS_LINK_IDLE,
18477 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018478 mutex_unlock(&pHddCtx->tdls_lock);
18479
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018480 if (status <= 0)
18481 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18483 "%s: Del station failed status %ld",
18484 __func__, status);
18485 return -EPERM;
18486 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018487
18488 /* TDLS Off Channel, Enable tdls channel switch,
18489 when their is only one tdls link and it supports */
18490 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18491 if (numCurrTdlsPeers == 1)
18492 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018493 tSirMacAddr peerMac;
18494 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018495
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018496 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018497 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018498
18499 if (connPeer == NULL) {
18500 mutex_unlock(&pHddCtx->tdls_lock);
18501 hddLog(VOS_TRACE_LEVEL_ERROR,
18502 "%s connPeer is NULL", __func__);
18503 return -EINVAL;
18504 }
18505
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018506 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18507 channel = connPeer->peerParams.channel;
18508
18509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18510 "%s: TDLS channel switch "
18511 "isOffChannelSupported %d "
18512 "isOffChannelConfigured %d "
18513 "isOffChannelEstablished %d",
18514 __func__,
18515 (connPeer ? connPeer->isOffChannelSupported : -1),
18516 (connPeer ? connPeer->isOffChannelConfigured : -1),
18517 (connPeer ? connPeer->isOffChannelEstablished : -1));
18518
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018519 if ((connPeer) &&
18520 (connPeer->isOffChannelSupported == TRUE) &&
18521 (connPeer->isOffChannelConfigured == TRUE))
18522 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018523 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018524 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018525 status = sme_SendTdlsChanSwitchReq(
18526 WLAN_HDD_GET_HAL_CTX(pAdapter),
18527 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018528 peerMac,
18529 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018530 TDLS_OFF_CHANNEL_BW_OFFSET,
18531 TDLS_CHANNEL_SWITCH_ENABLE);
18532 if (status != VOS_STATUS_SUCCESS) {
18533 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18534 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018535 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018536 else
18537 mutex_unlock(&pHddCtx->tdls_lock);
18538 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018539 else
18540 {
18541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18542 "%s: TDLS channel switch request not sent "
18543 "numCurrTdlsPeers %d ",
18544 __func__, numCurrTdlsPeers);
18545 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018546 }
18547 else
18548 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018549 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18551 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080018552 }
Bhargav Shah66896792015-10-01 18:17:37 +053018553 if (numCurrTdlsPeers == 0) {
18554 /* start TCP delack timer if TDLS is disable */
18555 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18556 hdd_manage_delack_timer(pHddCtx);
18557 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018558 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018559 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018560 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018561 {
Atul Mittal115287b2014-07-08 13:26:33 +053018562 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018563
Atul Mittal115287b2014-07-08 13:26:33 +053018564 if (0 != status)
18565 {
18566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018567 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053018568 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018569 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053018570 break;
18571 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018572 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018573 {
Atul Mittal115287b2014-07-08 13:26:33 +053018574 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
18575 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018576 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053018577 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018578
Atul Mittal115287b2014-07-08 13:26:33 +053018579 if (0 != status)
18580 {
18581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018582 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053018583 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053018584 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053018585 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018586 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018587 case NL80211_TDLS_DISCOVERY_REQ:
18588 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018590 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018591 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018592 return -ENOTSUPP;
18593 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18595 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018596 return -ENOTSUPP;
18597 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018598
18599 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018600 return 0;
18601}
Chilam NG571c65a2013-01-19 12:27:36 +053018602
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018603static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018604#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18605 const u8 *peer,
18606#else
18607 u8 *peer,
18608#endif
18609 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018610{
18611 int ret;
18612
18613 vos_ssr_protect(__func__);
18614 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
18615 vos_ssr_unprotect(__func__);
18616
18617 return ret;
18618}
18619
Chilam NG571c65a2013-01-19 12:27:36 +053018620int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
18621 struct net_device *dev, u8 *peer)
18622{
Arif Hussaina7c8e412013-11-20 11:06:42 -080018623 hddLog(VOS_TRACE_LEVEL_INFO,
18624 "tdls send discover req: "MAC_ADDRESS_STR,
18625 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018626#if TDLS_MGMT_VERSION2
18627 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18628 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18629#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018630#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18631 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18632 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
18633#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18634 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18635 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18636#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18637 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18638 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18639#else
Chilam NG571c65a2013-01-19 12:27:36 +053018640 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18641 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018642#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018643#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053018644}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018645#endif
18646
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018647#ifdef WLAN_FEATURE_GTK_OFFLOAD
18648/*
18649 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
18650 * Callback rountine called upon receiving response for
18651 * get offload info
18652 */
18653void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
18654 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
18655{
18656
18657 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018658 tANI_U8 tempReplayCounter[8];
18659 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018660
18661 ENTER();
18662
18663 if (NULL == pAdapter)
18664 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018666 "%s: HDD adapter is Null", __func__);
18667 return ;
18668 }
18669
18670 if (NULL == pGtkOffloadGetInfoRsp)
18671 {
18672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18673 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
18674 return ;
18675 }
18676
18677 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
18678 {
18679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18680 "%s: wlan Failed to get replay counter value",
18681 __func__);
18682 return ;
18683 }
18684
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018685 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18686 /* Update replay counter */
18687 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
18688 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18689
18690 {
18691 /* changing from little to big endian since supplicant
18692 * works on big endian format
18693 */
18694 int i;
18695 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18696
18697 for (i = 0; i < 8; i++)
18698 {
18699 tempReplayCounter[7-i] = (tANI_U8)p[i];
18700 }
18701 }
18702
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018703 /* Update replay counter to NL */
18704 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018705 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018706}
18707
18708/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018709 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018710 * This function is used to offload GTK rekeying job to the firmware.
18711 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018712int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018713 struct cfg80211_gtk_rekey_data *data)
18714{
18715 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18716 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18717 hdd_station_ctx_t *pHddStaCtx;
18718 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018719 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018720 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018721 eHalStatus status = eHAL_STATUS_FAILURE;
18722
18723 ENTER();
18724
18725 if (NULL == pAdapter)
18726 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018728 "%s: HDD adapter is Null", __func__);
18729 return -ENODEV;
18730 }
18731
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018732 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18733 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
18734 pAdapter->sessionId, pAdapter->device_mode));
18735
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018736 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018737 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018738 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018739 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018740 }
18741
18742 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18743 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18744 if (NULL == hHal)
18745 {
18746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18747 "%s: HAL context is Null!!!", __func__);
18748 return -EAGAIN;
18749 }
18750
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018751 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
18752 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
18753 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
18754 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018755 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018756 {
18757 /* changing from big to little endian since driver
18758 * works on little endian format
18759 */
18760 tANI_U8 *p =
18761 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
18762 int i;
18763
18764 for (i = 0; i < 8; i++)
18765 {
18766 p[7-i] = data->replay_ctr[i];
18767 }
18768 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018769
18770 if (TRUE == pHddCtx->hdd_wlan_suspended)
18771 {
18772 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018773 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
18774 sizeof (tSirGtkOffloadParams));
18775 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018776 pAdapter->sessionId);
18777
18778 if (eHAL_STATUS_SUCCESS != status)
18779 {
18780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18781 "%s: sme_SetGTKOffload failed, returned %d",
18782 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018783
18784 /* Need to clear any trace of key value in the memory.
18785 * Thus zero out the memory even though it is local
18786 * variable.
18787 */
18788 vos_mem_zero(&hddGtkOffloadReqParams,
18789 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018790 return status;
18791 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18793 "%s: sme_SetGTKOffload successfull", __func__);
18794 }
18795 else
18796 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18798 "%s: wlan not suspended GTKOffload request is stored",
18799 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018800 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018801
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018802 /* Need to clear any trace of key value in the memory.
18803 * Thus zero out the memory even though it is local
18804 * variable.
18805 */
18806 vos_mem_zero(&hddGtkOffloadReqParams,
18807 sizeof(hddGtkOffloadReqParams));
18808
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018809 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018810 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018811}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018812
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018813int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
18814 struct cfg80211_gtk_rekey_data *data)
18815{
18816 int ret;
18817
18818 vos_ssr_protect(__func__);
18819 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
18820 vos_ssr_unprotect(__func__);
18821
18822 return ret;
18823}
18824#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018825/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018826 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018827 * This function is used to set access control policy
18828 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018829static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18830 struct net_device *dev,
18831 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018832{
18833 int i;
18834 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18835 hdd_hostapd_state_t *pHostapdState;
18836 tsap_Config_t *pConfig;
18837 v_CONTEXT_t pVosContext = NULL;
18838 hdd_context_t *pHddCtx;
18839 int status;
18840
18841 ENTER();
18842
18843 if (NULL == pAdapter)
18844 {
18845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18846 "%s: HDD adapter is Null", __func__);
18847 return -ENODEV;
18848 }
18849
18850 if (NULL == params)
18851 {
18852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18853 "%s: params is Null", __func__);
18854 return -EINVAL;
18855 }
18856
18857 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18858 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018859 if (0 != status)
18860 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018861 return status;
18862 }
18863
18864 pVosContext = pHddCtx->pvosContext;
18865 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
18866
18867 if (NULL == pHostapdState)
18868 {
18869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18870 "%s: pHostapdState is Null", __func__);
18871 return -EINVAL;
18872 }
18873
18874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
18875 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018876 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18877 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
18878 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018879
18880 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
18881 {
18882 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
18883
18884 /* default value */
18885 pConfig->num_accept_mac = 0;
18886 pConfig->num_deny_mac = 0;
18887
18888 /**
18889 * access control policy
18890 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
18891 * listed in hostapd.deny file.
18892 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
18893 * listed in hostapd.accept file.
18894 */
18895 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
18896 {
18897 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
18898 }
18899 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
18900 {
18901 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
18902 }
18903 else
18904 {
18905 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18906 "%s:Acl Policy : %d is not supported",
18907 __func__, params->acl_policy);
18908 return -ENOTSUPP;
18909 }
18910
18911 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
18912 {
18913 pConfig->num_accept_mac = params->n_acl_entries;
18914 for (i = 0; i < params->n_acl_entries; i++)
18915 {
18916 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18917 "** Add ACL MAC entry %i in WhiletList :"
18918 MAC_ADDRESS_STR, i,
18919 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18920
18921 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
18922 sizeof(qcmacaddr));
18923 }
18924 }
18925 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
18926 {
18927 pConfig->num_deny_mac = params->n_acl_entries;
18928 for (i = 0; i < params->n_acl_entries; i++)
18929 {
18930 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18931 "** Add ACL MAC entry %i in BlackList :"
18932 MAC_ADDRESS_STR, i,
18933 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18934
18935 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
18936 sizeof(qcmacaddr));
18937 }
18938 }
18939
18940 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
18941 {
18942 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18943 "%s: SAP Set Mac Acl fail", __func__);
18944 return -EINVAL;
18945 }
18946 }
18947 else
18948 {
18949 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053018950 "%s: Invalid device_mode = %s (%d)",
18951 __func__, hdd_device_modetoString(pAdapter->device_mode),
18952 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018953 return -EINVAL;
18954 }
18955
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018956 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018957 return 0;
18958}
18959
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018960static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18961 struct net_device *dev,
18962 const struct cfg80211_acl_data *params)
18963{
18964 int ret;
18965 vos_ssr_protect(__func__);
18966 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
18967 vos_ssr_unprotect(__func__);
18968
18969 return ret;
18970}
18971
Leo Chang9056f462013-08-01 19:21:11 -070018972#ifdef WLAN_NL80211_TESTMODE
18973#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070018974void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070018975(
18976 void *pAdapter,
18977 void *indCont
18978)
18979{
Leo Changd9df8aa2013-09-26 13:32:26 -070018980 tSirLPHBInd *lphbInd;
18981 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053018982 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070018983
18984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018985 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070018986
c_hpothu73f35e62014-04-18 13:40:08 +053018987 if (pAdapter == NULL)
18988 {
18989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18990 "%s: pAdapter is NULL\n",__func__);
18991 return;
18992 }
18993
Leo Chang9056f462013-08-01 19:21:11 -070018994 if (NULL == indCont)
18995 {
18996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018997 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070018998 return;
18999 }
19000
c_hpothu73f35e62014-04-18 13:40:08 +053019001 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070019002 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070019003 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053019004 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070019005 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070019006 GFP_ATOMIC);
19007 if (!skb)
19008 {
19009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19010 "LPHB timeout, NL buffer alloc fail");
19011 return;
19012 }
19013
Leo Changac3ba772013-10-07 09:47:04 -070019014 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070019015 {
19016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19017 "WLAN_HDD_TM_ATTR_CMD put fail");
19018 goto nla_put_failure;
19019 }
Leo Changac3ba772013-10-07 09:47:04 -070019020 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070019021 {
19022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19023 "WLAN_HDD_TM_ATTR_TYPE put fail");
19024 goto nla_put_failure;
19025 }
Leo Changac3ba772013-10-07 09:47:04 -070019026 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070019027 sizeof(tSirLPHBInd), lphbInd))
19028 {
19029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19030 "WLAN_HDD_TM_ATTR_DATA put fail");
19031 goto nla_put_failure;
19032 }
Leo Chang9056f462013-08-01 19:21:11 -070019033 cfg80211_testmode_event(skb, GFP_ATOMIC);
19034 return;
19035
19036nla_put_failure:
19037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19038 "NLA Put fail");
19039 kfree_skb(skb);
19040
19041 return;
19042}
19043#endif /* FEATURE_WLAN_LPHB */
19044
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019045static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070019046{
19047 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
19048 int err = 0;
19049#ifdef FEATURE_WLAN_LPHB
19050 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070019051 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019052
19053 ENTER();
19054
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019055 err = wlan_hdd_validate_context(pHddCtx);
19056 if (0 != err)
19057 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019058 return err;
19059 }
Leo Chang9056f462013-08-01 19:21:11 -070019060#endif /* FEATURE_WLAN_LPHB */
19061
19062 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
19063 if (err)
19064 {
19065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19066 "%s Testmode INV ATTR", __func__);
19067 return err;
19068 }
19069
19070 if (!tb[WLAN_HDD_TM_ATTR_CMD])
19071 {
19072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19073 "%s Testmode INV CMD", __func__);
19074 return -EINVAL;
19075 }
19076
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019077 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19078 TRACE_CODE_HDD_CFG80211_TESTMODE,
19079 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070019080 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
19081 {
19082#ifdef FEATURE_WLAN_LPHB
19083 /* Low Power Heartbeat configuration request */
19084 case WLAN_HDD_TM_CMD_WLAN_HB:
19085 {
19086 int buf_len;
19087 void *buf;
19088 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080019089 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070019090
19091 if (!tb[WLAN_HDD_TM_ATTR_DATA])
19092 {
19093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19094 "%s Testmode INV DATA", __func__);
19095 return -EINVAL;
19096 }
19097
19098 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
19099 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080019100
19101 hb_params_temp =(tSirLPHBReq *)buf;
19102 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
19103 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
19104 return -EINVAL;
19105
Leo Chang9056f462013-08-01 19:21:11 -070019106 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
19107 if (NULL == hb_params)
19108 {
19109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19110 "%s Request Buffer Alloc Fail", __func__);
19111 return -EINVAL;
19112 }
19113
19114 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070019115 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
19116 hb_params,
19117 wlan_hdd_cfg80211_lphb_ind_handler);
19118 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070019119 {
Leo Changd9df8aa2013-09-26 13:32:26 -070019120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19121 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070019122 vos_mem_free(hb_params);
19123 }
Leo Chang9056f462013-08-01 19:21:11 -070019124 return 0;
19125 }
19126#endif /* FEATURE_WLAN_LPHB */
19127 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19129 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070019130 return -EOPNOTSUPP;
19131 }
19132
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019133 EXIT();
19134 return err;
Leo Chang9056f462013-08-01 19:21:11 -070019135}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019136
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053019137static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
19138#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
19139 struct wireless_dev *wdev,
19140#endif
19141 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019142{
19143 int ret;
19144
19145 vos_ssr_protect(__func__);
19146 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
19147 vos_ssr_unprotect(__func__);
19148
19149 return ret;
19150}
Leo Chang9056f462013-08-01 19:21:11 -070019151#endif /* CONFIG_NL80211_TESTMODE */
19152
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019153static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019154 struct net_device *dev,
19155 int idx, struct survey_info *survey)
19156{
19157 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19158 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053019159 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019160 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053019161 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019162 v_S7_t snr,rssi;
19163 int status, i, j, filled = 0;
19164
19165 ENTER();
19166
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019167 if (NULL == pAdapter)
19168 {
19169 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19170 "%s: HDD adapter is Null", __func__);
19171 return -ENODEV;
19172 }
19173
19174 if (NULL == wiphy)
19175 {
19176 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19177 "%s: wiphy is Null", __func__);
19178 return -ENODEV;
19179 }
19180
19181 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19182 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019183 if (0 != status)
19184 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019185 return status;
19186 }
19187
Mihir Sheted9072e02013-08-21 17:02:29 +053019188 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19189
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019190 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053019191 0 != pAdapter->survey_idx ||
19192 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019193 {
19194 /* The survey dump ops when implemented completely is expected to
19195 * return a survey of all channels and the ops is called by the
19196 * kernel with incremental values of the argument 'idx' till it
19197 * returns -ENONET. But we can only support the survey for the
19198 * operating channel for now. survey_idx is used to track
19199 * that the ops is called only once and then return -ENONET for
19200 * the next iteration
19201 */
19202 pAdapter->survey_idx = 0;
19203 return -ENONET;
19204 }
19205
Mukul Sharma9d5233b2015-06-11 20:28:20 +053019206 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
19207 {
19208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19209 "%s: Roaming in progress, hence return ", __func__);
19210 return -ENONET;
19211 }
19212
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019213 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19214
19215 wlan_hdd_get_snr(pAdapter, &snr);
19216 wlan_hdd_get_rssi(pAdapter, &rssi);
19217
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019218 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19219 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
19220 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019221 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
19222 hdd_wlan_get_freq(channel, &freq);
19223
19224
19225 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
19226 {
19227 if (NULL == wiphy->bands[i])
19228 {
19229 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
19230 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
19231 continue;
19232 }
19233
19234 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
19235 {
19236 struct ieee80211_supported_band *band = wiphy->bands[i];
19237
19238 if (band->channels[j].center_freq == (v_U16_t)freq)
19239 {
19240 survey->channel = &band->channels[j];
19241 /* The Rx BDs contain SNR values in dB for the received frames
19242 * while the supplicant expects noise. So we calculate and
19243 * return the value of noise (dBm)
19244 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
19245 */
19246 survey->noise = rssi - snr;
19247 survey->filled = SURVEY_INFO_NOISE_DBM;
19248 filled = 1;
19249 }
19250 }
19251 }
19252
19253 if (filled)
19254 pAdapter->survey_idx = 1;
19255 else
19256 {
19257 pAdapter->survey_idx = 0;
19258 return -ENONET;
19259 }
19260
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019261 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019262 return 0;
19263}
19264
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019265static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
19266 struct net_device *dev,
19267 int idx, struct survey_info *survey)
19268{
19269 int ret;
19270
19271 vos_ssr_protect(__func__);
19272 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
19273 vos_ssr_unprotect(__func__);
19274
19275 return ret;
19276}
19277
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019278/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019279 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019280 * this is called when cfg80211 driver resume
19281 * driver updates latest sched_scan scan result(if any) to cfg80211 database
19282 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019283int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019284{
19285 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19286 hdd_adapter_t *pAdapter;
19287 hdd_adapter_list_node_t *pAdapterNode, *pNext;
19288 VOS_STATUS status = VOS_STATUS_SUCCESS;
19289
19290 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019291
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019292 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019293 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019294 return 0;
19295 }
19296
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019297 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
19298 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019299 spin_lock(&pHddCtx->schedScan_lock);
19300 pHddCtx->isWiphySuspended = FALSE;
19301 if (TRUE != pHddCtx->isSchedScanUpdatePending)
19302 {
19303 spin_unlock(&pHddCtx->schedScan_lock);
19304 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19305 "%s: Return resume is not due to PNO indication", __func__);
19306 return 0;
19307 }
19308 // Reset flag to avoid updatating cfg80211 data old results again
19309 pHddCtx->isSchedScanUpdatePending = FALSE;
19310 spin_unlock(&pHddCtx->schedScan_lock);
19311
19312 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
19313
19314 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
19315 {
19316 pAdapter = pAdapterNode->pAdapter;
19317 if ( (NULL != pAdapter) &&
19318 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
19319 {
19320 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019321 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19323 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019324 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019325 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019326 {
19327 /* Acquire wakelock to handle the case where APP's tries to
19328 * suspend immediately after updating the scan results. Whis
19329 * results in app's is in suspended state and not able to
19330 * process the connect request to AP
19331 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053019332 hdd_prevent_suspend_timeout(2000,
19333 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019334 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019335 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019336
19337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19338 "%s : cfg80211 scan result database updated", __func__);
19339
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019340 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019341 return 0;
19342
19343 }
19344 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19345 pAdapterNode = pNext;
19346 }
19347
19348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19349 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019350 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019351 return 0;
19352}
19353
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019354int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
19355{
19356 int ret;
19357
19358 vos_ssr_protect(__func__);
19359 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
19360 vos_ssr_unprotect(__func__);
19361
19362 return ret;
19363}
19364
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019365/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019366 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019367 * this is called when cfg80211 driver suspends
19368 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019369int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019370 struct cfg80211_wowlan *wow)
19371{
19372 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019373 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019374
19375 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019376
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019377 ret = wlan_hdd_validate_context(pHddCtx);
19378 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019379 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019380 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019381 }
19382
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019383
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019384 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19385 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
19386 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019387 pHddCtx->isWiphySuspended = TRUE;
19388
19389 EXIT();
19390
19391 return 0;
19392}
19393
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019394int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19395 struct cfg80211_wowlan *wow)
19396{
19397 int ret;
19398
19399 vos_ssr_protect(__func__);
19400 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19401 vos_ssr_unprotect(__func__);
19402
19403 return ret;
19404}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019405
19406#ifdef FEATURE_OEM_DATA_SUPPORT
19407static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019408 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019409{
19410 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19411
19412 ENTER();
19413
19414 if (wlan_hdd_validate_context(pHddCtx)) {
19415 return;
19416 }
19417 if (!pMsg)
19418 {
19419 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
19420 return;
19421 }
19422
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019423 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019424
19425 EXIT();
19426 return;
19427
19428}
19429
19430void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019431 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019432{
19433 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19434
19435 ENTER();
19436
19437 if (wlan_hdd_validate_context(pHddCtx)) {
19438 return;
19439 }
19440
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019441 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019442
19443 switch(evType) {
19444 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019445 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019446 break;
19447 default:
19448 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
19449 break;
19450 }
19451 EXIT();
19452}
19453#endif
19454
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019455#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19456 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019457/**
19458 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
19459 * @wiphy: Pointer to wiphy
19460 * @wdev: Pointer to wireless device structure
19461 *
19462 * This function is used to abort an ongoing scan
19463 *
19464 * Return: None
19465 */
19466static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19467 struct wireless_dev *wdev)
19468{
19469 struct net_device *dev = wdev->netdev;
19470 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
19471 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
19472 int ret;
19473
19474 ENTER();
19475
19476 if (NULL == adapter) {
19477 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
19478 return;
19479 }
19480
19481 ret = wlan_hdd_validate_context(hdd_ctx);
19482 if (0 != ret)
19483 return;
19484
19485 wlan_hdd_scan_abort(adapter);
19486
19487 return;
19488}
19489
19490/**
19491 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
19492 * @wiphy: Pointer to wiphy
19493 * @wdev: Pointer to wireless device structure
19494 *
19495 * Return: None
19496 */
19497void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19498 struct wireless_dev *wdev)
19499{
19500 vos_ssr_protect(__func__);
19501 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
19502 vos_ssr_unprotect(__func__);
19503
19504 return;
19505}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019506#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019507
Jeff Johnson295189b2012-06-20 16:38:30 -070019508/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019509static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070019510{
19511 .add_virtual_intf = wlan_hdd_add_virtual_intf,
19512 .del_virtual_intf = wlan_hdd_del_virtual_intf,
19513 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
19514 .change_station = wlan_hdd_change_station,
19515#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
19516 .add_beacon = wlan_hdd_cfg80211_add_beacon,
19517 .del_beacon = wlan_hdd_cfg80211_del_beacon,
19518 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019519#else
19520 .start_ap = wlan_hdd_cfg80211_start_ap,
19521 .change_beacon = wlan_hdd_cfg80211_change_beacon,
19522 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070019523#endif
19524 .change_bss = wlan_hdd_cfg80211_change_bss,
19525 .add_key = wlan_hdd_cfg80211_add_key,
19526 .get_key = wlan_hdd_cfg80211_get_key,
19527 .del_key = wlan_hdd_cfg80211_del_key,
19528 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019529#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070019530 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019531#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019532 .scan = wlan_hdd_cfg80211_scan,
19533 .connect = wlan_hdd_cfg80211_connect,
19534 .disconnect = wlan_hdd_cfg80211_disconnect,
19535 .join_ibss = wlan_hdd_cfg80211_join_ibss,
19536 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
19537 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
19538 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
19539 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070019540 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
19541 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053019542 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070019543#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19544 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
19545 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
19546 .set_txq_params = wlan_hdd_set_txq_params,
19547#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019548 .get_station = wlan_hdd_cfg80211_get_station,
19549 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
19550 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019551 .add_station = wlan_hdd_cfg80211_add_station,
19552#ifdef FEATURE_WLAN_LFR
19553 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
19554 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
19555 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
19556#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019557#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
19558 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
19559#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019560#ifdef FEATURE_WLAN_TDLS
19561 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
19562 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
19563#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019564#ifdef WLAN_FEATURE_GTK_OFFLOAD
19565 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
19566#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019567#ifdef FEATURE_WLAN_SCAN_PNO
19568 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
19569 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
19570#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019571 .resume = wlan_hdd_cfg80211_resume_wlan,
19572 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019573 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070019574#ifdef WLAN_NL80211_TESTMODE
19575 .testmode_cmd = wlan_hdd_cfg80211_testmode,
19576#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019577 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019578#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19579 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019580 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019581#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019582};
19583